Python-初始化父类

时间:2019-02-06 20:18:53

标签: python inheritance

我试图弄清楚如何使用super()根据条件一个接一个地初始化父类。

class A:
    def __init__(self, foo):
        self.foo = foo

class B:
    def __init__(self, bar):
        self.bar == bar

class C(A,B):
    def __init__(self):
        #Initialize class A first.
        #Do some calculation and then initialize class B 

如何在class C中使用super()使其仅首先初始化class A,然后进行一些计算并调用super()来初始化class B

2 个答案:

答案 0 :(得分:2)

您无法按照C.__init__的要求进行操作,因为super不能控制特定继承方法的调用方式,只能控制调用顺序,即完全由父类的列出顺序控制。

如果您使用super,则需要在所有 all 类中一致使用它。 (这就是为什么它被称为 cooperative 继承的原因。)请注意,这意味着C不能在对A.__init__B.__init__的调用之间插入任何代码。

__init__在使用super时正确实施特别棘手,因为super的规则是您必须期望传递任意参数,而object.__init__()却没有不要接受任何争论。您需要每个附加参数都由特定的根类“拥有”,该根类负责将其从参数列表中删除。

class A:
    def __init__(self, foo, **kwargs):
        # A "owns" foo; pass everything else on
        super().__init__(**kwargs)
        self.foo = foo

class B:
    def __init__(self, bar, **kwargs):
        # B "owns" bar; pass everything else on
        super().__init__(**kwargs)
        self.bar = bar

class C(A,B):
    def __init__(self):
        # Must pass arguments expected by A and B
        super().__init__(foo=3, bar=9)

C的MRO为[A, B, object],因此调用树看起来像这样:

  1. C.__init__不带任何参数调用
  2. super()解析为A,因此A.__init__foo=3bar=9调用。
  3. A.__init__中,super()解析为B,因此B.__init__bar=9调用。
  4. B.__init__中,super()解析为object,因此调用object.__init__时不带参数(kwargs为空)
  5. object.__init__返回后,self.bar设置为bar
  6. B.__init__返回后,self.foo设置为foo
  7. A.__init__返回后,C.__init__完成

好的,第一句话并不完全正确。由于AB都没有使用super,因此,您可能可以假设适当地使用super会简单地使用class A: def __init__(self, foo): self.foo = foo class B: def __init__(self, bar): self.bar == bar class C(A,B): def __init__(self): super(A, self).__init__(foo=3) # Do some calculation super(B, self).__init__(bar=9) 调用一个父函数并立即返回。

A

不过,我不确定,这不会引入一些难以预测的错误,这些错误可能会在BC和/或{{1 }}尝试正确使用super

答案 1 :(得分:0)

您实际上可以显式引用基类:

class A:
    def __init__(self, foo):
        self.foo = foo

class B:
    def __init__(self, bar):
        self.bar == bar

class C(A,B):
    def __init__(self):
        A.__init__(self, 'foovalue')
        # Do some calculation
        B.__init__(self, 'barvalue')