Meh*_*dad 10 python multiple-inheritance super diamond-problem python-3.x
究竟是为什么
A.__init__()
B.__init__()
D.__init__()
Run Code Online (Sandbox Code Playgroud)
由以下代码打印?特别是:
为什么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()
Run Code Online (Sandbox Code Playgroud)
B.__init__
那是应该C.__init__
通过的super(B, self).__init__()
,你绕过了那个电话.为什么C .__ init __()没有打印?
因为你没有告诉它.多重继承涉及合作,你使用了明确的类引用,否认合作.
如果你用super().__init__()
(因为你已经标记它为Python 3)替换了所有"超类似"的调用,你会看到如下输出:
A.__init__()
C.__init__()
B.__init__()
D.__init__()
Run Code Online (Sandbox Code Playgroud)
实际上,如果你改变了只是B
"超级喜欢"的调用,你会看到这个输出:
super(B, self).__init__()
super().__init__()
Run Code Online (Sandbox Code Playgroud)
那么为什么A不能在你的情况下调用C?
在网站的其他地方复制关于MRO的精心设计的答案是多余的.
如果我把super().__ init __()代替A .__ init __(self),为什么打印C .__ init __()?
因为无参数的super()从左到右,所以B
首先查看,然后在B中你使用显式的类引用(A.__init__(self)
).而在这样做,你失去所有d(最*)方面也有一个超类C
.
super()
是什么可以帮助你导航MRO,并且如果C.__init__()
你让它让你得到它.但是B
你只是在称一种类的方法A
.
*正如你所指出的那样C.__init__()
,永远不会被召唤.但是,C
仍然显示在D.__bases__
:
(<class '__main__.B'>, <class '__main__.C'>)
Run Code Online (Sandbox Code Playgroud)
在D.__mro__
:
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
Run Code Online (Sandbox Code Playgroud)
和isinstance(D(), C) is True
.
简而言之,Python 知道这C
是一个超类D
,但是你给了C.__init__
你的B.__init__
实现和最终运行.