super
的Python文档指出:
这对于访问已在类中重写的继承方法非常有用。
在不覆盖method
的子类中调用super().method()
有什么意义吗?
对我来说没有,因为调用self.method()
是等价的,也就是说继承在self
的超类中会method
查找,使用相同的type(self).__mro__
方法解析顺序(由self
超类层次结构的C3线性化给出)而不是super
。
所以对我来说,super
在这种情况下很有用:
class A:
def f(self):
print("A")
class B:
pass
class C(B, A):
def f(self):
super().f()
print("C")
C().f() # prints A C
但不是在这个:
class A:
def f(self):
print("A")
class B:
pass
class C(B, A):
def g(self):
super().f() # should be just self.f()
print("C")
C().g() # prints A C
正如@chepner所指出的,在不覆盖method
的子类中调用super().method()
并不等同于调用self.method()
。差异出现在覆盖method
的该子类的子类中。
比较:
class A:
def f(self):
print("A")
class B:
pass
class C(B, A):
def g(self):
super().f() # == super(C, self).f(), so lookup starts after C in type(self).__mro__
print("C")
class D(C):
def f(self):
print("D")
D().g() # prints A C, since D.__mro__ == (D, C, B, A, object)
跟:
class A:
def f(self):
print("A")
class B:
pass
class C(B, A):
def g(self):
self.f() # lookup starts at the beginning in type(self).__mro__
print("C")
class D(C):
def f(self):
print("D")
D().g() # prints D C, since D.__mro__ == (D, C, B, A, object)