用super为多个父类调用init? [复制]

Posted

技术标签:

【中文标题】用super为多个父类调用init? [复制]【英文标题】:calling init for multiple parent classes with super? [duplicate] 【发布时间】:2011-12-22 05:18:15 【问题描述】:

可能重复:Can Super deal with multiple inheritance?

Python 继承?我有一个类结构(如下),并希望子类调用父母双方的__init__。这是否可能以“超级”方式进行,还是只是一个糟糕的想法?

class Parent1(object):
    def __init__(self):
        self.var1 = 1

class Parent2(object):
    def _init__(self):
        self.var2 = 2

class Child(Parent1, Parent2):
    def __init__(self):
        ## call __init__ of Parent1
        ## call __init__ of Parent2
        ## super(Child, self).__init__()

【问题讨论】:

【参考方案1】:

super() 的想法是您不必费心分别调用两个超类的 __init__() 方法 -- super() 会处理它,只要您正确使用它 -- 请参阅 Raymond Hettinger's "Python’s super() considered super!" 了解一个解释。

也就是说,我经常发现 super() 对于构造函数调用的缺点超过了优点。例如,您的所有构造函数都需要提供额外的**kwargs 参数,所有类必须协作,非协作外部类需要包装器,您必须注意每个构造函数参数名称在所有中都是唯一的> 你的课程等等。

所以通常情况下,我认为为构造函数调用显式命名要调用的基类方法更容易:

class Child(Parent1, Parent2):
    def __init__(self):
        Parent1.__init__(self)
        Parent2.__init__(self)

我确实将super() 用于具有保证原型的函数,例如__getattr__()。在这些情况下没有缺点。

【讨论】:

【参考方案2】:

你可以直接用Parent.__init__(self)打电话给他们:

class Parent1(object):
    def __init__(self):
        self.var1 = 1

class Parent2(object):
    def __init__(self):
        self.var2 = 2

class Child(Parent1, Parent2):
    def __init__(self):
        Parent1.__init__(self)
        Parent2.__init__(self)
        print(self.var1, self.var2)

【讨论】:

【参考方案3】:

通过super 调用不会调用所有父级,它会调用MRO 链中的下一个函数。要使其正常工作,您需要在所有 __init__s 中使用 super

class Parent1(object):
    def __init__(self):
        super(Parent1, self).__init__()
        self.var1 = 1

class Parent2(object):
    def __init__(self):
        super(Parent2, self).__init__()
        self.var2 = 2

class Child(Parent1, Parent2):
    def __init__(self):
        super(Child, self).__init__()

在 Python 3 中,您可以使用 super() 代替 super(type, instance)

【讨论】:

我阅读了许多其他问题和答案,您的问题和答案是唯一指出super() 如何调用“MRO 链中的下一个功能”的问题和答案。确实是一个简单但非常重要的声明。 对于那些不知道什么是 MRO 的人:python.org/download/releases/2.3/mro 如果Parent1和Parent2内置在模块类中会怎样?

以上是关于用super为多个父类调用init? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

Python3基础 super层层调用父类的__init__方法 子类的__init__覆盖了父类的__init__的解决方法

super,多继承

Python3基础 super 子类调用父类的__init__

Python3基础 super 子类调用父类的__init__

面向对象super内置函数(转)

python语言中多继承中super调用所有父类的方法以及要用到的MRO顺序