在不覆盖方法的子类中调用 super().method()



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)

最新更新