是否不会自动调用Mixin类__init__函数?
我想使用Mixin始终向子类添加一些初始化功能,每个子类都继承自不同的API基类。具体来说,我想制作多个不同的子类,这些子类继承自这些API提供的不同基类之一和一个Mixin,后者始终将以相同的方式执行Mixin初始化代码,而无需代码复制。但是,除非我在Child类的__init__函数中显式调用它,否则似乎永远不会调用Mixin类的__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)
顺便说一句,如果我所有的子类都继承自相同的基类,我意识到我可以创建一个新的中类,该中类继承自基类和mixin并保持DRY的状态。但是,它们从具有通用功能的不同基类继承。(准确地说是Django
Field类)。
-
抱歉,我这么晚才看到,但是
class MixedClass2(SomeMixin, MyClass): pass >>> m = MixedClass2() mixin before base mixin after
@Ignacio谈论的模式称为合作多重继承,这很棒。但是,如果基类对合作不感兴趣,则将其作为第二个基础,而将其混入第一个。在
__init__()
Python的MRO之后,将在基类之前检查mixin
(及其定义的其他内容)。尽管我不确定它能处理您的特定用途,但这应该可以解决一般性问题。具有自定义元类(例如Django模型)或奇怪的装饰器(例如@ martineau’s
answer;)的基类可以做疯狂的事情。