当最终类没有__init__时,不调用Python mixin构造函数

Ale*_*zyk 1 python multiple-inheritance super mixins

最终类用户可能想创建一个由Base和组成的类MixinMixin在第三方库类上提供了其他通用功能)。

但是,Mixin.__init__当按以下方式使用时不会调用。仅Base.__init__称为:

>>> class Base(object): #3rd party library class
...     def __init__(self): print "Base"
... 
>>> class Mixin(object): #my features useful as addendum for a few classes
...     def __init__(self): print "Mixin"
... 
>>> class C(Base, Mixin): pass
... 
>>> c = C()
Base
Run Code Online (Sandbox Code Playgroud)

如何执行调用都Mixin.__init__Base.__init__在这种情况下,无需用户记住把一个构造函数super()在C级呼叫?

>>> class Base(object):
...     def __init__(self): print "Base"
... 
>>> class Mixin(object):
...     def __init__(self): print "Mixin"
... 
>>> class C(Base, Mixin): 
...    #easy to forget to add constructor 
...    def __init__(self): super(C, self).__init__()
... 
>>> c = C()
Base
Mixin
Run Code Online (Sandbox Code Playgroud)

che*_*ner 5

Python不会自动链接任何像这样的方法调用,因此您需要受纪律并正确使用协作继承。如果使用一个类super,则所有类都必须使用super。(这是一个简单的情况,因为没有一个重写的__init__方法会添加任何其他参数。如果这样做,则需要做一些工作以确保object.__init__一旦被调用就永远不会收到其他参数。)

在继续之前,请先阅读https://rhettinger.wordpress.com/2011/05/26/super-considered-super/

class Base(object):
    def __init__(self):
        print "Base"
        super(Base, self).__init__()

class Mixin(object):
    def __init__(self):
        print "Mixin"
        super(Mixin, self).__init__()

class C(Base, Mixin): 
    pass

c = C()
Run Code Online (Sandbox Code Playgroud)

(这也是为什么您需要了解其super工作原理,而不是将其视为对类的基类的简单间接引用的完美示例。)

如果您不能修改BaseMixin使用super,则需要围绕它们定义包装器。链接的文章解释了如何。