当final类没有__init__时,没有调用Python mixin构造函数

时间:2016-01-25 17:35:04

标签: python multiple-inheritance mixins super

最终类用户可能希望创建一个由BaseMixin组成的类(Mixin提供了超过第三方库类的其他常用功能。)

但如下所示,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

如何强制在此方案中同时调用Mixin.__init__Base.__init__,而无需用户记住在C类中调用带有super()调用的构造函数?

>>> 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

1 个答案:

答案 0 :(得分:3)

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()

(这也是一个很好的例子,说明为什么你需要了解super的工作原理,将它视为对你班级基类的简单间接引用。)

如果您无法修改BaseMixin以使用super,那么您需要定义包围它们的包装器。链接的文章解释了如何。