Python子类可以通过调用super()进行初始化,也可以不通过调用进行初始化,如下所示
class Parent(object):
...
class Child(Parent):
def __init__(self):
super(Child, self).__init__()
class Child(Parent):
def __init__(self):
Parent.__init__(self)这两种情况之间有什么区别,一种情况通常比另一种更可取吗?
发布于 2015-03-21 02:38:27
super的目的是处理继承菱形。如果类继承结构只使用单继承,那么使用super()将导致与显式调用“父”类相同的调用。
考虑一下这个继承菱形:
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可以避免这些陷阱。
发布于 2015-03-21 02:39:09
super(Child, self).__init__()的主要目的是允许初始化在具有菱形继承结构的多重继承的情况下正确运行。如果显式调用具有多个继承的基类构造函数,则某些初始化器可能会被调用两次。对于单继承,使用超级方法和显式调用基类__init__()方法在功能上没有区别。请注意,因为所有的python新样式类都是子类对象,所以多重继承总是涉及菱形继承。
如果您重命名或更改基类,则super的好处较少,可以减少所需的更改。
在Python3中,super的参数是可选的,所以您可以只使用super().__init__()。Python 2仍然要求您显式地提供参数。
https://stackoverflow.com/questions/29173299
复制相似问题