编辑:我在 Python 3 。
我有一个X
课,它同时延伸Y
和Z
:
class X(Y, Z):
def __init__(self):
# Call Y's __init__
# Call Z's __init
pass
我需要通过__init__
上Y
的{{1}}和Z
致电__init__
。最好的方法是什么?
答案 0 :(得分:2)
这完全取决于Y
和Z
设计是否与多重继承合作。如果是,那么您应该只能使用super
:
class X(Y, Z):
def __init__(self):
super().__init__()
当我说Y
和Z
需要设计为与多重继承协同工作时,我的意思是他们还必须使用__init__
方法调用super:
class Y:
def __init__(self):
print('Y.__init__')
super().__init__()
class Z:
def __init__(self):
print('Z.__init__')
super().__init__()
它们也应该有一些处理不同参数的策略,因为类(特别是构造函数)经常在它们接受的关键字参数方面有所不同。在这一点上,值得阅读Super considered super!和Super considered harmful以了解一些关于超级的常见习语和陷阱。
如果您不知道Y
和Z
是否是为合作多重继承而设计的,那么最安全的办法是假设它们不是。
如果这些类不适用于合作多重继承,那么你需要开始轻轻踩(你处于危险的水域)。您可以单独调用每个__init__
:
class X(Y, Z):
def __init__(self):
Y.__init__(self)
Z.__init__(self)
但真的最好不要使用多重继承,而是选择不同的范例(例如作文)。
答案 1 :(得分:2)
通常,没有其他方法可以直接调用Y.__init__(self)
和Z.__init__(self)
。这是确保两个构造函数至少被称为 的唯一方法。
然而,在一些奇怪的(或正常的,取决于你如何看待它)的情况下,这会导致非常不直观的结果,其中基础构造函数被多次调用:
class Y:
def __init__(self):
print('Y')
super().__init__()
class Z:
def __init__(self):
print('Z')
super().__init__()
class X(Y, Z):
def __init__(self):
print('X')
Y.__init__(self)
Z.__init__(self)
X()
结果
X
Y
Z
Z
因此,super().__init__()
X
中的.__init__()
(而不是Y
次调用)看起来很自然,并且可以正常运行。但是,如果Z
和super().__init__()
也未调用scenChoice <- c("X2010", "SSP2-NoCC-REF", "SSP1-NoCC-REF", "SSP3-NoCC-REF", "SSP2-GFDL-REF", "SSP2-IPSL-REF", "SSP2-HGEM-REF")
,则会失败。在这种情况下,您只能调用其中一个构造函数。
因此,一般情况下,如果不了解基类的实现,就无法正确解决问题。
YARtAMI =避免多重继承的另一个原因