Python-初始化父类



我正试图弄清楚如何使用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

您不能在C.__init__中执行您的要求,因为super不能控制调用哪些特定的继承方法,只能控制调用它们的顺序,并且完全由父类的列出顺序控制。

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

当使用super时,__init__要正确实现尤其困难,因为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],所以调用树看起来像这样:

调用C.__init__时没有参数
  • super()解析为A,因此用foo=3bar=9调用A.__init__
  • A.__init__中,super()解析为B,因此用bar=9调用B.__init__
  • B.__init__中,super()解析为object,因此调用object.__init__时不带任何参数(kwargs为空)
  • 一旦object.__init__返回,self.bar被设置为bar
  • 一旦B.__init__返回,self.foo设置为foo
  • 一旦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)
    

    不过,我不完全确定这是否会引入一些难以预测的错误,这些错误可能会在AB和/或C的其他子类中出现,这些子类试图正确使用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):
    A.__init__(self, 'foovalue')
    # Do some calculation
    B.__init__(self, 'barvalue')
    

    最新更新