【问题标题】:Python mixin constructor not called when final class has no __init__当最终类没有 __init__ 时未调用 Python mixin 构造函数
【发布时间】:2016-05-02 02:55:32
【问题描述】:

最终类用户可能想要创建一个由BaseMixin 组成的类(Mixin 提供了超过 3rd 方库类的额外通用功能)。

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__,而不需要用户记住将带有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

【问题讨论】:

  • C.__init__ 不会同时打印;它调用Base.__init__,它不调用任何进一步的函数。

标签: python multiple-inheritance mixins super


【解决方案1】:

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,那么您需要围绕它们定义可以的包装器。链接的文章解释了如何。

【讨论】:

    猜你喜欢
    • 2015-01-24
    • 2012-02-17
    • 2018-05-30
    • 1970-01-01
    • 1970-01-01
    • 2011-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多