我试图弄清楚如何使用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
答案 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]
,因此调用树看起来像这样:
C.__init__
不带任何参数调用super()
解析为A
,因此A.__init__
被foo=3
和bar=9
调用。A.__init__
中,super()
解析为B
,因此B.__init__
被bar=9
调用。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
和/或{{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')