可以使用或不调用super()
来初始化Python子类,如下所示
class Parent(object):
...
class Child(Parent):
def __init__(self):
super(Child, self).__init__()
class Child(Parent):
def __init__(self):
Parent.__init__(self)
这些案件之间有什么区别,并且通常比另一案件更受欢迎?
答案 0 :(得分:24)
超级的目的是处理继承钻石。如果上课 继承结构只使用单继承,然后使用super()将 导致与显式调用" parent"相同的调用。类。
考虑这个继承钻石:
class A(object):
def __init__(self):
print('Running A.__init__')
super(A,self).__init__()
class B(A):
def __init__(self):
print('Running B.__init__')
super(B,self).__init__()
class C(A):
def __init__(self):
print('Running C.__init__')
super(C,self).__init__()
class D(B,C):
def __init__(self):
print('Running D.__init__')
super(D,self).__init__()
foo = D()
打印
Running D.__init__
Running B.__init__
Running C.__init__
Running A.__init__
如果我们将B
更改为B2
并使用对父__init__
的显式调用:
class B2(A):
def __init__(self):
print('Running B.__init__')
A.__init__(self)
class D2(B2,C):
def __init__(self):
print('Running D.__init__')
super(D2,self).__init__()
bar = D2()
然后init调用链变为
Running D.__init__
Running B.__init__
Running A.__init__
因此完全跳过对C.__init__
的调用。
没有一个首选方案。
如果您可以保证您不想支持多重继承 显式父调用更简单,更清晰。
如果您希望现在或将来支持多重继承,则需要使用super()
。但是要明白使用super会涉及some pitfalls,但是proper use可以避免这些陷阱。
答案 1 :(得分:8)
super(Child, self).__init__(self)
的主要目的是允许在使用菱形继承结构进行多重继承的情况下正确运行初始化。如果显式调用具有多个继承的基类构造函数,则可能会调用两次初始化程序。使用单继承,使用super和显式调用基类__init__()
方法之间没有功能差异。请注意,因为所有python新样式类都是子类对象,所以多重继承总是涉及钻石继承。
super减少需求更改的好处较小。
在python 3中,super
的参数是可选的,因此你可以super().__init__(self)
。 Python 2仍然要求您明确提供参数。