在这个多重继承示例中从基(根)类调用 super 有什么意义?

问题描述 投票:0回答:1

这是我试图运行的代码,它试图使用 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 调用就可以正常工作了?

python-3.x multiple-inheritance super keyword-argument method-resolution-order
1个回答
0
投票

三角形类似乎没有初始化,但这怎么可能呢? 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__
将永远不会运行。

© www.soinside.com 2019 - 2024. All rights reserved.