python多重继承:避免以菱形形状两次调用构造函数 [英] python multiple inheritance: avoid calling the constructors twice in diamond shape
问题描述
考虑以下代码:
class A(object):
def __init__(self):
print("A.__init__")
super(A, self).__init__() # 1
print("A.__init__ finished")
class B(A):
def __init__(self):
print("B.__init__")
super(B, self).__init__() # 2
print("B.__init__ finished")
class C(A):
def __init__(self):
print("C.__init__")
super(C, self).__init__()
print("C.__init__ finished")
class D(B, C):
def __init__(self):
print("D.__init__")
print("Initializing B")
B.__init__(self) # 3
print("B initialized")
print("Initializing C")
C.__init__(self) # 4
print("C initialized")
print("D.__init__ finished")
D()
# D.__init__
# Initializing B
# B.__init__
# C.__init__
# A.__init__
# A.__init__ finished
# C.__init__ finished
# B.__init__ finished
# B initialized
# Initializing C
# C.__init__
# A.__init__
# A.__init__ finished
# C.__init__ finished
# C initialized
# D.__init__ finished
据我了解,算法如下:
D.__init__ at (3) -> B.__init__ ->
-> super().__init__ -> (super of self.__class__).__init__ ->
-> C.__init__ (# why C?) -> super().__init__ ->
-> A.__init__
D.__init__ at (4) -> C.__init__ ->
-> super().__init__ ->
-> A.__init__
实际上有三个问题:
1.为什么当self
是D
的实例时,为什么super().__init__()
调用B.__init__
(在2)会调用C.__init__
?
2.在这种情况下,如何避免两次调用C.__init__
和A.__init__
?
2.1初始化当前类继承的所有类的正确方法是什么?
Actually there are three questions:
1. Why super().__init__()
call in B.__init__
(at 2) calls C.__init__
when self
is an instance of D
?
2. How to avoid calling C.__init__
and A.__init__
twice in this case?
2.1 What is the right way to initialize all the classes the current class inherits from?
推荐答案
Q:当self是D的实例时,为什么B.__init__
(在2)处的super().__init__()
调用会调用C.__init__
? >
Q: Why super().__init__()
call in B.__init__
(at 2) calls C.__init__
when self is an instance of D?
致电时
super(X, self).__init__
Python查找 MRO self.__class__.mro()
.然后,它会在X之后从MRO中的 next 类调用__init__
.
Python looks up the MRO self.__class__.mro()
. It then calls __init__
from the next class in the MRO after X.
当self是D
的实例时,self.__class__.mro()
是[D, B, C, A]
.因此super(B, self).__init__()
调用C.__init__(self)
.
When self is an instance of D
, self.__class__.mro()
is [D, B, C, A]
. So super(B, self).__init__()
calls C.__init__(self)
.
问:初始化当前类继承的所有类的正确方法是什么?
还要在D.__init__
中使用超级:
class D(B, C):
def __init__(self):
print("D.__init__")
super(D, self).__init__()
print("D.__init__ finished")
这篇关于python多重继承:避免以菱形形状两次调用构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!