Mixin类__init__函数是不是自动调用的? [英] Are Mixin class __init__ functions not automatically called?

查看:166
本文介绍了Mixin类__init__函数是不是自动调用的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用Mixin总是为我的子类添加一些init功能,每个子类都继承自不同的API基类。具体来说,我想创建多个不同的子类,这些子类继承自这些不同的API提供的基类之一和一个Mixin,它将始终以相同的方式执行Mixin初始化代码,而无需代码复制。但是,看起来Mixin类的__init__函数永远不会被调用,除非我在Child类的__init__函数中明确地调用它,这不太理想。我已经构建了一个简单的测试用例:

I'd like to use a Mixin to always add some init functionality to my child classes which each inherit from different API base classes. Specifically, I'd like to make multiple different child classes that inherit from one of these different API-supplied base classes and the one Mixin, which will always have the Mixin initialization code executed in the same way, without code replication. However, it seems that the __init__ function of the Mixin class never gets called unless I explicitly call it in the Child class's __init__ function, which is less than ideal. I've built up a simple test case:

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永远不会被调用:

As you can see in the following output, the Mixin function's init never gets called:

>>> import test
>>> test.MixedClass()
 base
<test.MixedClass object at 0x1004cc850>

有没有办法做到这一点(在调用Mixin时有一个init函数)而不是每一个都写子类显式调用Mixin的init函数? (即,不必在每个班级做这样的事情:)

Is there a way to do this (have an init function in a Mixin get called) without writing every child class to explicitly invoke the Mixin's init function? (i.e., without having to do something like this in every class:)

class MixedClass(MyClass, SomeMixin):
    def __init__(*args, **kwargs):
        SomeMixin.__init__(self, *args, **kwargs)
        MyClass.__init__(self, *args, **kwargs) 

顺便说一下,如果我所有的子类都继承自相同的基类,我意识到我可以创建一个继承的新中间类从基类和mixin中保持干燥。但是,它们从具有共同功能的不同基类继承。 (准确地说是Django Field类)。

Btw, if all my child classes were inheriting from same base class, I realize I could create a new middle class that inherits from the base class and the mixin and keep it DRY that way. However, they inherit from different base classes with common functionality. (Django Field classes, to be precise).

推荐答案

对不起我这么晚才看到这个,但是

Sorry I saw this so late, but

class MixedClass2(SomeMixin, MyClass):
    pass

>>> m = MixedClass2()
 mixin before 
 base 
 mixin after

@Ignacio所讨论的模式称为协同多重继承,它很棒。但是如果基类对合作不感兴趣,那么将它作为第二个基础,并将其作为第一个基础。在Python的 __ init __()(以及它定义的任何其他内容)。下载/发布/ 2.3 / mro /> MRO

The pattern @Ignacio is talking about is called cooperative multiple inheritance, and it's great. But if a base class isn't interested in cooperating, make it the second base, and your mixin the first. The mixin's __init__() (and anything else it defines) will be checked before the base class, following Python's MRO.

这应解决一般性问题,但我不确定它是否处理您的具体用途。具有自定义元类(如Django模型)或奇怪的装饰器(如@ martineau的答案;)的基类可以做疯狂的事情。

This should solve the general question, though I'm not sure it handles your specific use. Base classes with custom metaclasses (like Django models) or with strange decorators (like @martineau's answer ;) can do crazy things.

这篇关于Mixin类__init__函数是不是自动调用的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆