为什么在多重继承中执行 Base.__init__(self) 而不是 super().__init__() 时会跳过 __init__?
Why is an __init__ skipped when doing Base.__init__(self) in multiple inheritance instead of super().__init__()?
为什么恰好是
A.__init__()
B.__init__()
D.__init__()
通过以下代码打印?特别是:
为什么C.__init__()
没有打印出来?
为什么我把 super().__init__()
而不是 A.__init__(self)
打印成 C.__init__()
?
#!/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__
应该通过 super(B, self).__init__()
调用 C.__init__
,而你绕过了那个调用。
为什么不打印C.__init__()?
因为你没有告诉它。多重继承涉及合作,您使用了明确的 class 引用,否认合作。
如果您将所有 "super-like" 调用替换为 super().__init__()
(因为您已将其标记为 Python 3),您会看到如下输出:
A.__init__()
C.__init__()
B.__init__()
D.__init__()
事实上,如果您仅将 B
的 "super-like" 调用更改为:
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 中使用显式 class 引用 (A.__init__(self)
)。在这样做的过程中,你失去了 D also 作为超级class C
的所有(大多数*)上下文。
super()
是帮助您驾驭 MRO 的东西,如果您愿意,本可以让您到达 C.__init__()
。但是在 B
中,您只是调用了 A
.
的 class 方法
*如您所见,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
的超级class,但是你给出了 C.__init__
和 end-运行 与您的 B.__init__
实施。
为什么恰好是
A.__init__()
B.__init__()
D.__init__()
通过以下代码打印?特别是:
为什么
C.__init__()
没有打印出来?为什么我把
super().__init__()
而不是A.__init__(self)
打印成C.__init__()
?
#!/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__
应该通过 super(B, self).__init__()
调用 C.__init__
,而你绕过了那个调用。
为什么不打印C.__init__()?
因为你没有告诉它。多重继承涉及合作,您使用了明确的 class 引用,否认合作。
如果您将所有 "super-like" 调用替换为 super().__init__()
(因为您已将其标记为 Python 3),您会看到如下输出:
A.__init__()
C.__init__()
B.__init__()
D.__init__()
事实上,如果您仅将 B
的 "super-like" 调用更改为:
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 中使用显式 class 引用 (A.__init__(self)
)。在这样做的过程中,你失去了 D also 作为超级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
的超级class,但是你给出了 C.__init__
和 end-运行 与您的 B.__init__
实施。