在Python中具有多重继承的MRO

MRO with multiple inheritance in python

在python网页上的文档中,python中经典类的方法解析顺序描述为从左到右的深度优先搜索。我试着用这段代码来测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class A(object):
def __init__(self):
    print"Initialized A"

class B(A):
    def test():
        print"Initialized B"

class C(A):
    def __init__(self):
        print"Initialized C"

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

当我创建对象D的实例时:

1
D()

我得到结果:

1
2
Initialized C
Initialized D

由于MRO是深度优先的,所以我希望打印的是"初始化A"、"初始化D",而初始化首先在B中搜索,如果找不到(就是这种情况),它应该在层次结构中更深一层,并在B的基类(即A)中查找函数。有人能给我解释一下为什么我得到了c的init函数而不是a的init函数吗?


您的类继承自object,因此不是经典类。这是一个新式的班级。(从新样式类继承的任何类也是新样式类。)

注意,super无论如何不能与经典类一起使用。您引用的"深度从左到右优先"规则只是在尝试访问实例上未直接定义的属性时搜索订单基类的属性查找规则。经典类不提供这样的MRO——没有任何方法可以在不显式引用特定超类的情况下访问属性的"超类值"。


D的MRO为:

1
2
print(D.mro())
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>]

所以

1
super(D, self).__init__()

D之后的self.__class__.mro()的第一类中查找__init__方法。由于B没有__init__方法,因此在C中寻找__init__方法。它找到了C.__init__,因此

1
super(D, self).__init__()

调用C.__init__(self)

注意,super不是试图访问getattr(B, __init__)。相反,它在B.__dict__中寻找'__init__'