Python 3 super()如何在这种特殊的多继承情况下工作?

时间:2016-09-10 06:06:42

标签: python-3.x multiple-inheritance super

我有以下代码:

class A:
    def __init__(self):
        print("A.__init__")

class B(A):
    def __init__(self):
        print("B.__init__")
        super().__init__()

class C(A):
    def __init__(self):
        print("C.__init__")
        super().__init__()


class D(B,C):
    def __init__(self):
        print("D.__init__")
        super().__init__()

当我从D类实例化一个对象时,

d = D()

我得到了:

>>> d = D()
D.__init__
B.__init__
C.__init__
A.__init__

为什么A类的__init__()只被召唤一次,最后一次?请注意,B类和C类都称为A类__init__(),所以我希望A类的__init__()应该被调用两次。

我阅读了Python 3的文档和Hettinger先生的博客,但没有弄清楚底层机制。那么super()如何确定它只需要执行一次呢?感谢。

1 个答案:

答案 0 :(得分:0)

Python有一种称为方法解析顺序(MRO)的机制,用于在类层次结构中查找适当的方法。 MRO中有两条规则:

1- dept-first first-left-right search

2-只考虑最后一次出现的课程

现在回到你的例子:

予。搜索从D开始,将其添加到MRO列表[D]。

II。 D类继承自B和C. B是最左边的父,然后是C.所以MRO列表变为[D,B,C]。

III。然后搜索继续到更深层次,其中B的父项被添加到列表中。现在我们有[D,B,C,A]。 继续搜索C的父母,再次是A.因为A已经在列表中,所以没有任何变化。

IV。搜索进入更深层次(A的父母)并且因为A没有任何明确的父级,搜索在此时结束。

所以最后的清单是[D,B,C,A]。

super()方法使用此列表完成其工作,这就是为什么A在最后被调用