Python - 为多个父类调用__init__

时间:2016-09-09 15:31:36

标签: python-3.x

编辑:我在 Python 3

我有一个X课,它同时延伸YZ

class X(Y, Z):
    def __init__(self):
    # Call Y's __init__
    # Call Z's __init
    pass

我需要通过__init__Y的{​​{1}}和Z致电__init__。最好的方法是什么?

2 个答案:

答案 0 :(得分:2)

这完全取决于YZ 设计是否与多重继承合作。如果是,那么您应该只能使用super

class X(Y, Z):
    def __init__(self):
        super().__init__()

当我说YZ需要设计为与多重继承协同工作时,我的意思是他们还必须使用__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以了解一些关于超级的常见习语和陷阱。

如果您不知道YZ是否是为合作多重继承而设计的,那么最安全的办法是假设它们不是。

如果这些类不适用于合作多重继承,那么你需要开始轻轻踩(你处于危险的水域)。您可以单独调用每个__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次调用)看起来很自然,并且可以正常运行。但是,如果Zsuper().__init__()也未调用scenChoice <- c("X2010", "SSP2-NoCC-REF", "SSP1-NoCC-REF", "SSP3-NoCC-REF", "SSP2-GFDL-REF", "SSP2-IPSL-REF", "SSP2-HGEM-REF") ,则会失败。在这种情况下,您只能调用其中一个构造函数。

因此,一般情况下,如果不了解基类的实现,就无法正确解决问题。

YARtAMI =避免多重继承的另一个原因