如何使用super调用多个父类的初始化?

23 投票
3 回答
24918 浏览
提问于 2025-04-17 05:39

可能重复的问题:
super能处理多重继承吗?

关于Python的继承,我有一个类的结构(如下所示),我想让子类同时调用两个父类的__init__方法。这可以用“super”的方式实现吗?还是说这是个糟糕的主意?

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

3 个回答

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

super()的意思是,你不需要单独去调用父类的__init__()方法,只要正确使用super(),它会自动帮你处理这些事情。想了解更多,可以看看Raymond Hettinger的文章《Python的super()被认为是超级的!》

不过,我发现对于构造函数来说,super()的缺点往往超过了它的优点。例如,你的所有构造函数都需要额外提供一个**kwargs参数,所有类之间必须要配合,外部不配合的类还需要一个包装器,你还得确保每个构造函数的参数名在所有类中都是唯一的等等。

所以大多数情况下,我觉得明确地指定你想调用的基类方法会更简单:

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

不过,对于那些有固定原型的函数,比如__getattr__(),我还是会使用super()。在这些情况下没有什么缺点。

27

通过 super 调用并不是调用所有父类的方法,而是调用继承链中的下一个函数。为了让这个过程正常工作,你需要在所有的 __init__ 方法中都使用 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)

撰写回答