这是我试图运行的代码,它试图使用 Python 中的多重继承的概念来计算右金字塔的面积
class Rectangle:
def __init__(self, length, width, **kwargs):
self.length = length
self.width = width
print("I am in Rectangle")
print(kwargs)
super().__init__(**kwargs)
def area(self):
return self.length * self.width
def perimeter(self):
return 2 * self.length + 2 * self.width
# Here we declare that the Square class inherits from
# the Rectangle class
class Square(Rectangle):
def __init__(self, length, **kwargs):
super().__init__(length=length, width=length, **kwargs)
print("I am in Square")
class Cube(Square):
def surface_area(self):
face_area = super().area()
return face_area * 6
def volume(self):
face_area = super().area()
return face_area * self.length
class Triangle:
def __init__(self, base, height, **kwargs):
self.base = base
self.height = height
super().__init__(**kwargs)
print("I am in Triangle")
def tri_area(self):
return 0.5 * self.base * self.height
class RightPyramid(Square, Triangle):
def __init__(self, base, slant_height, **kwargs):
self.base = base
self.slant_height = slant_height
kwargs["height"] = slant_height
kwargs["length"] = base
print(kwargs)
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
当我用这行代码运行它时,它就实现了它的目的
rrp = RightPyramid(2,2,height=3,length=4)
rrp.area_2()
运行上面的代码得到 12 作为答案。但是当我修改 Rectangle 类以删除 super 调用时:
class Rectangle:
def __init__(self, length, width, **kwargs):
self.length = length
self.width = width
print(f"I am in Rectangle")
print(kwargs)
然后尝试执行area_2()函数,它会抛出一个错误:
“属性错误:‘RightPyramid’对象没有属性‘高度’”
三角形类似乎没有初始化,但这怎么可能呢? RightPyramid 继承自正方形和三角形,因此来自 RightPyramid 的 super 调用应该初始化这两个类,而不管是否从根类调用 super。为什么在根类中添加 super 调用就可以正常工作了?
三角形类似乎没有初始化,但这怎么可能呢? RightPyramid 继承自正方形和三角形,因此超级调用 来自 RightPyramid 的应该初始化这两个类,无论 super 被从根类调用。
这是不正确的。
这是
RightPyramid
的方法解析顺序(MRO):
In [2]: RightPyramid.mro()
Out[2]:
[__main__.RightPyramid,
__main__.Square,
__main__.Rectangle,
__main__.Triangle,
object]
如您所见,
Rectangle
是MRO中的倒数第二个,因此如果它不调用super().__init__
,那么MRO中的最后一个类Triangle.__init__
将永远不会运行。