gpt4 book ai didi

python - 为什么这个继承结构是这样构建的呢?

转载 作者:行者123 更新时间:2023-12-05 06:01:02 24 4
gpt4 key购买 nike

几天来我一直在努力理解这段代码的细节:

class Rectangle:
def __init__(self, length, width, **kwargs):
self.length = length
self.width = width
super().__init__(**kwargs)

def area(self):
return self.length * self.width

def perimeter(self):
return 2 * self.length + 2 * self.width

# Square inherits from Rectangle:
class Square(Rectangle):
def __init__(self, length, **kwargs):
super().__init__(length=length, width=length, **kwargs)


# Triangle doesn't inherit from any class:
class Triangle:
def __init__(self, base, height, **kwargs):
self.base = base
self.height = height
super().__init__(**kwargs)

def tri_area(self):
return 0.5 * self.base * self.height

# Pyramid inherits from square and triangle:
class Pyramid(Square, Triangle):
def __init__(self, base, slant_height, **kwargs):
self.base = base
self.slant_height = slant_height

# Adding attributes to kwargs dictionary
kwargs["height"] = slant_height
kwargs["length"] = base
super().__init__( base=base, **kwargs)

def area(self):
base_area = super().area()
perimeter = super().perimeter()
return 0.5 * perimeter * self.slant_height + base_area

def area_2(self):
base_area = super().area()
triangle_area = super().tri_area()
return triangle_area * 4 + base_area

继承树是这样的:

Rectangle 
\
Square Triangle
\ /
Pyramid

Pyramid 类的 MRO:

(__main__.Pyramid,
__main__.Square,
__main__.Rectangle,
__main__.Triangle,
object)

我了解代码背后的总体思路,以及如何使用 super().__init__ 使用 **kwargs 将可变关键字参数字典传递给父类(super class).我遇到问题的详细信息是:

  1. 为什么我们在 Pyramid 类中使用 base=base 而父类(super class) (Square) 采用 length 参数?
  2. 当我只放置 super().__init__(base, **kwargs) 而不是 base=base 时,为什么会报错说 init() 得到参数 'length' 的多个值, 是因为上面指定的 kwargs["length"] 吗?如果是这样,base=base 是如何解决的?
  3. 为什么我们在 Rectangle 中没有父类(super class)时有 super().__init__(**kwargs)?我的猜测可能是将 kwargs 传递给内置的 object 基类,以便 Triangle 可以继承它?但我不确定。
  4. 为什么 Triangle 也会调用基类?这似乎是多余的(即使从 Triangle 中删除 super().__init__(**kwargs) 也不会改变任何东西)。

最佳答案

好问题!

  1. 因为 Square.__init__ 接受 **kwargs 我们实际上可以传递我们想要的任何东西给它而不会得到一个意外的关键字参数错误1。这稍后会变得很方便。它(和/或其父类(super class)的 __init__ 方法)不使用的任何关键字参数都将在 MRO 中向上传播,直到我们到达 object


    1通常。在这种情况下,(不必要的)调用Triangle.__init__ 中的

    super().__init__(**kwargs) 打破了这种行为。


  1. 由于kwargs的扩展,在Pyramid.__init__调用super().__init__(base, **kwargs)时code>,Square.__init__实际上是用(2, height=3, length=2)调用的。由于 Square.__init__ 的参数称为 length,您会收到关于 length 的多个值的错误。

  2. 没错。此外,因为还没有任何东西“消耗”base 关键字参数,Triangle.__init__ 将接收它。

  3. 这也是正确的。绝对没有必要在 Triangle.__init__ 中调用 super().__init__(**kwargs),尤其是到那时 kwargs 是一个空字典(它包含的所有关键字参数都已经被使用)。

关于python - 为什么这个继承结构是这样构建的呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67359334/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com