在Python网页上的文档中,Python中经典类的方法解析顺序被描述为深度优先的从左到右搜索。我试着用这段代码来测试:
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的实例时:
D()
我得到了结果:
Initialized C
Initialized D
虽然我期望打印"初始化A","初始化D",因为MRO是深度优先的,初始化首先在B中搜索,当没有找到(就是这种情况)时,它应该在层次结构中更深入,并在B的基类中寻找函数(即A)。有人能给我一个解释为什么我得到C的初始化函数而不是A的函数吗?
D
的MRO为:
print(D.mro())
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>]
super(D, self).__init__()
在D
之后的self.__class__.mro()
的第一类中寻找__init__
方法。由于B
没有__init__
,因此它在C
中查找__init__
方法。它找到C.__init__
,因此
super(D, self).__init__()
调用C.__init__(self)
.
注意super
没有试图访问getattr(B, __init__)
。相反,它正在B.__dict__
中寻找'__init__'
。
您的类继承自object
,因此不是一个经典类。这是一个新型的班级。(任何从new-style类继承的类也是new-style类)
注意super
无论如何都不能与经典类一起使用。您引用的"深度优先从左到右"规则只是在尝试访问实例上没有直接定义的属性时搜索基类的顺序的属性查找规则。经典类不提供这样的MRO——没有任何方法可以访问属性的"超类值",而不显式地引用特定的超类。