假设我使用的库提供以下类:
class A:
def __init__(self):
print("A")
class B(A):
def __init__(self):
print("B")
super().__init__()
然后我定义一个mixin和一个子类:
class C:
def __init__(self):
print("C")
super().__init__()
class D(B, C):
def __init__(self):
print("D")
super().__init__()
创建新的D
的输出是
D
B
A
我的目标是在初始化D时也调用C的__init__
,而不能修改B或A。期望的输出是
D
B
A
C
在多重继承中使用super
有很多问题,比如this one和this one。从this post中,我了解到要使协作子类模式工作,并且要调用C.__init__
,B
和A
还需要调用super
,这将以方法解析顺序返回C
。Hettinger建议编写一个适配器类来处理这种“不合作”的情况。我可以为B编写一个适配器类,但与Hettinger的示例不同,B是我从中继承的主要类,而不是mixin。我的理解是,我必须“重写”B在其适配器中实现的每个方法才能工作,这似乎是不可行的,特别是如果B是一个将来可能改变行为的大型库类。你知道吗
那么,有没有什么方法可以在不调整B或A的情况下获得C的初始化行为呢?你知道吗
混合的黄金法则:
总是先从mixin继承。你知道吗
适当的mixin被设计为支持多重继承,即它们有一个带有
*args, **kwargs
的构造函数来调用super().__init__(*args, **kwargs)
(或者它们根本没有构造函数)。像这样的构造函数是完全透明和不可见的;它不会妨碍子类的构造函数。你知道吗当子类(
D
)调用super().__init__()
时,它将调用mixin的(C
)构造函数,后者将依次调用B
的构造函数。换句话说,只需重新排序D
的父类就可以解决问题。你知道吗如果出于某种原因,必须按
D B A C
的顺序调用构造函数,则应显式调用父类的构造函数,而不使用super()
:相关问题 更多 >
编程相关推荐