我想使用 Mixin 始终向我的子类添加一些初始化功能,每个子类都继承自不同的 API 基类。具体来说,我想制作多个不同的子类,它们继承自这些不同的 API 提供的基类之一和一个 Mixin,它们将始终以相同的方式执行 Mixin 初始化代码,而无需代码复制。但是,似乎 Mixin 类的 init 函数永远不会被调用,除非我在 Child 类的 init 函数中明确调用它,这不太理想。我建立了一个简单的测试用例:
class APIBaseClassOne(object):
def __init__(self, *args, **kwargs):
print (" base ")
class SomeMixin(object):
def __init__(self, *args, **kwargs):
print (" mixin before ")
super(SomeMixin, self).__init__(*args, **kwargs)
print (" mixin after ")
class MyClass(APIBaseClassOne):
pass
class MixedClass(MyClass, SomeMixin):
pass
正如您在以下输出中看到的,Mixin 函数的 init 永远不会被调用:
>>> import test
>>> test.MixedClass()
base
<test.MixedClass object at 0x1004cc850>
有没有办法做到这一点(在 Mixin 中调用一个 init 函数)而不用编写每个子类来显式调用 Mixin 的 init 函数? (即,不必在每个班级都做这样的事情:)
class MixedClass(MyClass, SomeMixin):
def __init__(*args, **kwargs):
SomeMixin.__init__(self, *args, **kwargs)
MyClass.__init__(self, *args, **kwargs)
顺便说一句,如果我所有的子类都继承自同一个基类,我意识到我可以创建一个新的中间类,它继承自基类和混合类,并以这种方式保持干燥。但是,它们继承自具有共同功能的不同基类。 (Django Field 类,准确地说)。
原文由 B Robster 发布,翻译遵循 CC BY-SA 4.0 许可协议
对不起,我这么晚才看到这个,但是
@Ignacio 正在谈论的模式称为合作多重继承,它很棒。但是如果一个基类对合作不感兴趣,就把它作为第二个基类,把你的 mixin 作为第一个。在 Python 的 MRO 之后,mixin 的
__init__()
(以及它定义的任何其他内容)将在基类之前被检查。这应该可以解决一般问题,但我不确定它是否可以处理您的特定用途。具有自定义元类(如 Django 模型)或具有奇怪装饰器(如@martineau 的回答;)的基类可以做一些疯狂的事情。