在Python webpage的文档中,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
虽然我期望打印“Initialized A”,“Initialized D”,因为MRO是深度优先的,首先在B中搜索初始化,如果没有找到(这种情况),它应该在层次结构中更深入在B的基类中寻找函数(即A)。有人可以给我一个解释,为什么我得到C的init函数而不是A的那个?
答案 0 :(得分:4)
D
的MRO是:
print(D.mro())
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>]
所以
super(D, self).__init__()
在__init__
之后的self.__class__.mro()
中的第一个班级中查找D
方法。由于B
没有__init__
,因此会在__init__
中查找C
方法。它找到C.__init__
,因此
super(D, self).__init__()
致电C.__init__(self)
。
请注意,super
并未尝试访问getattr(B, __init__)
。相反,它正在'__init__'
中寻找B.__dict__
。
答案 1 :(得分:4)
您的类继承自object
,因此不是经典类。这是一个新式的课程。 (任何继承自新式类的类也是新式类。)
请注意,super
无论如何都不能与经典类一起使用。您引用的“从左到右的深度”规则只是在您尝试访问未在实例上直接定义的属性时搜索订单基类的属性查找规则。经典类不提供MRO本身 - 没有任何方法可以访问属性的“超类值”而无需显式引用特定的超类。