我一直在努力理解 super()
在多重继承的上下文中的行为。我很困惑为什么在 test2.py 的父类中调用 super()
会导致为父类调用 __init__()
?
test1.py
#!/usr/bin/env python
class A(object):
def __init__(self):
self.A = "A"
print self.A
class B(object):
def __init__(self):
self.B = "B"
print self.B
class C(A, B):
def __init__(self):
self.C = "C"
print self.C
super(C, self).__init__()
if __name__ == '__main__':
print "Without super() in parent __init__():"
c = C()
print c.__dict__
print C.__mro__
产生:
$ ./test.py
Without super() in parent __init__():
C
A
{'A': 'A', 'C': 'C'}
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <type 'object'>)
test2.py
#!/usr/bin/env python
class A(object):
def __init__(self):
self.A = "A"
print self.A
super(A, self).__init__()
class B(object):
def __init__(self):
self.B = "B"
print self.B
super(B, self).__init__()
class C(A, B):
def __init__(self):
self.C = "C"
print self.C
super(C, self).__init__()
if __name__ == '__main__':
print "With super() in parent __init__():"
c = C()
print c.__dict__
print C.__mro__
产生:
$ ./test2.py
With super() in parent __init__():
C
A
B
{'A': 'A', 'C': 'C', 'B': 'B'}
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <type 'object'>)
最佳答案
你的错误在你的评论中:
super(C, self).__init__() <-- call to object.__init__()
这不是对 object.__init__
的调用。您将类 C 和实例 self
都传递给 super
的原因是它知道接下来要调用什么,而不仅仅是基于类的父类(super class),而是基于实例的 MRO。本质上,super(C, self).__init__
的意思是“在自己的 MRO 中调用 C 之后类的 __init__
”。
这就是 super
的全部要点 --- 它允许合作继承,其中一个类可以调用 super
来表示“将控制传递给 MRO 中的下一个类” ,而无需在类定义时知道是哪个类。
所以当你调用 super(C, self).__init__
时,它会调用 A.__init__
,因为 A 是 MRO 中 C 之后的下一个类。然后当 A 调用 super(A, self).__init__
时,调用 B.__init__
,因为 B 是 MRO 中 A 之后的类。
(请注意,您的消息以相反的顺序打印 --- B、A、C --- 因为您在调用父类(super class)方法之后打印了每条消息。所以第一条消息没有得到打印直到执行一直到 B.__init__
,然后其他消息在返回继承树的路上打印。)
关于python - 为什么在父类 __init__() 中调用 super() 会改变子类 __init__() 的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17269270/