super
可以避免代码重复;一个复杂的__init__
不需要被复制/粘贴到你的继承类中。它还使MRO按照应有的方式工作,这样如果你使用多重继承,它将正确地工作。
这样做的一个原因是确保所有继承对象都具有某些来自父类缺少的属性。如果你只是编写一个新的__init__
,除非你重复你的代码,否则它们将没有这些属性。例如:
>>> class A(object):
... def __init__(self, x):
... self.x = x
...
>>> class B(A):
... def __init__(self, y):
... self.y = y
...
>>> Stick = B(15)
>>> Stick.x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'B' object has no attribute 'x'
>>>
在
__init__
期间不调用
super
将完全覆盖整个方法。在这里调用
super
可以确保两个变量存在于继承类中。
>>> class C(A):
... def __init__(self, x, y):
... super(C, self).__init__(x)
... self.y = y
...
>>> Dave = C(15, 22)
>>> Dave.x
15
>>> Dave.y
22
>>>
请注意在
super
调用中,
x
被传递给
__init__()
调用,但是
self
在代码的
super(C,self)
部分被处理。
编辑:TyrantWave也正确指出,在
__init__
之外,
super
也非常有用。以一个简单的
foo
方法为例子。
class Parent(object):
def foo(self):
return "I say foo!"
继承类可能只想修改此函数的输出,而不是完全重写它。因此,我们不要重复自己并重复编写相同的代码,只需调用
super
来获取父类的返回值,然后处理数据并返回子类修改后的结果。
class Child(Parent):
def foo(self):
parent_result = super(Child, self).foo()
return "I'm a child!! %s" % parent_result
在上面的代码中,调用
super
会返回
Parent
类中
foo()
方法的值,然后
Child
类会进一步处理数据并将其返回。
>>> Alan = Parent()
>>> Stan = Child()
>>> Alan.foo()
'I say foo!'
>>> Stan.foo()
"I'm a child!! I say foo!"
>>>