我已经转换你的代码Python3(通过改变print
到print()
),并增加了一些更多的跟踪语句:
class A(object):
def __init__(self):
print("A", type(self).__mro__)
super(A, self).__init__()
print("/A")
class B(object):
def __init__(self):
print("B", type(self).__mro__)
super(B, self).__init__()
print("/B")
class C(A,B):
def __init__(self):
print("C")
A.__init__(self)
print("ca/b")
B.__init__(self)
print("/C")
C()
下面是输出:
C
A (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
B (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
/B
/A
ca/b
B (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
/B
/C
望着输出,你可以看到调用C.__init__
方法正在发生的事情,并打印“C”。然后直接调用A.__init__
(这是一个错误 - 使用super
!)。
A.__init__
调用打印其消息,包括__mro__
属性。您可以看到序列:C - > A - > B - > Object。这很重要,因为这意味着从A.__init__
内调用super()
将参考类B
。另外,如果您允许,自C.__init__
内部调用super
将自动调用A.__init__
。
如上所述,下一个方法B.__init__
由A.__init__
内的super
引用调用。它叫Object.__init__
,据推测,这不会打印任何东西。 ;-)
两个B.__init__
和A.__init__
回报,我们看到的中点消息ca/b
,然后你到B.__init__
直接调用。它会打印一条消息,但再次参考super
表单B.__init__
什么也不做,因为B
位于MRO的尾部。
super()
机制可以为您处理所有这些MRO的东西。您不应该调用A.__init__(self)
。相反,你可以让super
处理它,里面C.__init__
,但是这样做:
class C(A,B):
def __init__(self):
print("C")
super(C, self).__init__()
这是如此之大!谢谢 – TreeCatCat