22

可能重复:
Super 可以处理多重继承吗?

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

3 回答 3

42

的想法super()是您不必费心__init__()分别调用两个超类的方法——super()只要你正确使用它,就会处理它——请参阅Raymond Hettinger 的“Python 的 super() 被认为是超级的!” 解释一下。

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

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

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

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

于 2011-11-04T17:04:42.000 回答
26

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

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

于 2011-11-04T17:06:23.337 回答
13

您可以直接使用以下命令调用它们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)
于 2011-11-04T17:05:52.803 回答