我正试图弄清楚如何使用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=3
和bar=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__
结束好吧,第一句话并不完全正确。由于当前编写的A
和B
都不使用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
、B
和/或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')