我有 2 个类,每个类都实现特定行为并使用父类。
现在我有一个新类需要使用任一行为,但只能在构造期间/之后确定哪一个行为。
目前这是通过使用多重继承来完成的。 然而,由于基类的编写并未考虑到这一点,因此包含的
super()
调用将调用错误的子树
考虑以下 MWE:
class A:
def __init__(self, use_b):
self.init_b = use_b # Maybe complicated
def foo(self):
print("A")
class B(A):
def foo(self):
super().foo()
print("B")
class C1(A):
def foo(self):
super().foo()
print("C1")
class C2(C1):
def foo(self):
super().foo()
print("C2")
class D(B, C2):
def __init__(self, *args):
super().__init__(*args)
self.use_b = self.init_b
def foo(self):
if self.use_b:
B.foo(self)
else:
C2.foo(self)
d = D(True)
d.foo()
print("NEXT")
d = D(False)
d.foo()
在
A
中的某个位置初始化了一个属性,该属性在 D
中使用来确定要使用的适当类。两个候选者 B
和 C2
都继承自基类,因为它们现在/曾经是独立的实现
它适用于调用
C2.foo
,但调用B.foo
最终会在foo
和C2
中调用C1
,这是我不想要的。
我确实知道为什么会发生这种情况(MRO),但没有好主意来解决这个问题。
我也许可以让
D
仅继承于 A
,初始化它,然后决定使用哪个子类,即:
class D(A):
def __init__(self, *args):
super().__init__(*args)
if self.init_b:
self.impl = B(*args)
else:
self.impl = C2(*args)
def foo(self):
self.impl.foo()
但这有3个问题:
A
多次。这对性能不利,如果 A.__init__
修改引用类型参数(例如列表),可能会失败B
和 C2
理解,那么 A
无法处理它们,它可能会失败A
的 all方法。如果我忘记了被
B
或 C
类覆盖的一个,则行为将默默地错误。类似的属性有没有一种干净、安全的方法来处理这种情况?
super
的可选参数:
class D(B, C2):
def __init__(self, *args):
super().__init__(*args)
self.use_b = self.init_b
def foo(self):
if self.use_b:
super(B, self).foo()
else:
super(C2, self).foo()