假设我有多个继承方案:
class A(object):
# code for A here
class B(object):
# code for B here
class C(A, B):
def __init__(self):
# What's the right code to write here to ensure
# A.__init__ and B.__init__ get called?
编写
C
的__init__
有两种典型方法:(旧式)
ParentClass.__init__(self)
(较新样式)
super(DerivedClass, self).__init__()
但是,无论哪种情况,如果父类(
A
和B
)don't follow the same convention, then the code will not work correctly(某些类可能会丢失,或者被多次调用)。那么又是什么正确的方法呢?说“保持一致,遵循一个或另一个”很容易,但是如果
A
或B
来自第三方库,那又会怎样呢?有没有一种方法可以确保所有父类构造函数都被调用(以正确的顺序,并且只能调用一次)?编辑:看看我的意思,如果我这样做:
class A(object):
def __init__(self):
print("Entering A")
super(A, self).__init__()
print("Leaving A")
class B(object):
def __init__(self):
print("Entering B")
super(B, self).__init__()
print("Leaving B")
class C(A, B):
def __init__(self):
print("Entering C")
A.__init__(self)
B.__init__(self)
print("Leaving C")
然后我得到:
Entering C
Entering A
Entering B
Leaving B
Leaving A
Entering B
Leaving B
Leaving C
请注意,
B
的init被调用两次。如果我做:class A(object):
def __init__(self):
print("Entering A")
print("Leaving A")
class B(object):
def __init__(self):
print("Entering B")
super(B, self).__init__()
print("Leaving B")
class C(A, B):
def __init__(self):
print("Entering C")
super(C, self).__init__()
print("Leaving C")
然后我得到:
Entering C
Entering A
Leaving A
Leaving C
请注意,永远不会调用
B
的init。因此,似乎除非我知道/控制我从中继承的类(A
和B
)的初始化,否则我无法对正在编写的类(C
)做出安全的选择。
最佳答案
两种方式都可以正常工作。使用super()
的方法为子类带来了更大的灵活性。
在直接调用方法中,C.__init__
可以同时调用A.__init__
和B.__init__
。
使用super()
时,需要将这些类设计为协作多重继承,其中C
调用super
,这将调用A
的代码,该调用还将调用super
,这将调用B
的代码。有关使用super
可以执行的操作的更多详细信息,请参见http://rhettinger.wordpress.com/2011/05/26/super-considered-super。
[回答问题,稍后编辑]
因此,似乎除非我知道/控制类的初始化,否则,
继承自(A和B)我不能为自己所在的班级做出安全的选择
写作(C)。
参考的文章显示了如何通过在A
和B
周围添加包装器类来处理这种情况。标题为“如何合并非合作类”的部分提供了一个可行的示例。
可能希望多重继承更容易,让您毫不费力地组合Car和Airplane类来获得FlyingCar,但现实情况是,单独设计的组件通常需要适配器或包装器,然后才能像我们希望的那样无缝地组装在一起:-)
还有一种想法:如果您不满意使用多重继承来编写功能,则可以使用composition来完全控制在哪些情况下调用哪些方法。
关于python - 用多重继承调用父类__init__,正确的方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55549401/