如何使用super调用多个父类的初始化?
可能重复的问题:
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)
。