为什么正是是
A.__init__()
B.__init__()
D.__init__()
由以下代码打印?特别是:
为什么是
C.__init__()
未打印?为什么是
C.__init__()
如果我把super().__init__()
打印出来而不是A.__init__(self)
?
#!/usr/bin/env python3
class A(object):
def __init__(self):
super(A, self).__init__()
print("A.__init__()")
class B(A):
def __init__(self):
A.__init__(self)
print("B.__init__()")
class C(A):
def __init__(self):
A.__init__(self)
print("C.__init__()")
class D(B, C):
def __init__(self):
super(D, self).__init__()
print("D.__init__()")
D()
最佳答案
tl;dr:因为B.__init__
应该叫C.__init__
通过super(B, self).__init__()
, 你绕过了那个电话。
为什么不打印 C.__init__()?
因为你没有告诉它。多重继承涉及合作,您使用了显式类引用,否认了合作。
你是否用 super().__init__()
替换了所有“ super 相似”的调用? (因为您已将其标记为 Python 3)您会看到如下输出:
A.__init__()
C.__init__()
B.__init__()
D.__init__()
事实上,如果您只更改 B
,您会看到此输出对其中之一的“ super 喜欢”调用:
super(B, self).__init__()
super().__init__()
那么在你的案例中为什么 A 没有给 C 打电话呢?
复制网站上其他地方关于 MRO 的概述清晰的答案是多余的。
- How does Python's super() work with multiple inheritance?
- How does Python's "super" do the right thing?
如果我使用 super().__init__() 而不是 A.__init__(self) 为什么会打印 C.__init__()?
因为 the no-argument super() goes left to right , 所以 B
首先查看,然后在 B 内部使用显式类引用 ( A.__init__(self)
)。在这样做的过程中,你失去了 D 也作为父类(super class)的所有(大多数*)上下文 C
.
super()
是什么帮助您导航 MRO,并会让您到达 C.__init__()
如果你让它。但是在B
你只是在调用 A
的类方法.
*如您所见C.__init__()
永远不会被调用。然而,C
仍然出现在 D.__bases__
中:
(<class '__main__.B'>, <class '__main__.C'>)
在D.__mro__
:
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
和isinstance(D(), C) is True
.
简而言之,Python 知道 C
是 D
的父类(super class), 但你给了 C.__init__
然后用你的B.__init__
结束运行实现。
关于python - 为什么在多重继承中执行 Base.__init__(self) 而不是 super().__init__() 时会跳过 __init__?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52685876/