Python中super()的本质、MRO机制与常见应用场景详解
本文深入解析Python中super()的本质,指出其并非简单调用父类方法,而是遵循C3算法确定的MRO顺序执行。通过具体代码示例,演示了super()在指定父类方法调用及增量扩展父类功能(如重写list的append方法)中的实际应用,帮助开发者正确理解并避免常见的继承陷阱。
一、什么是super
1. super本质上是一个类,而非普通方法或内置关键字。
class A:
pass
print(type(super(A)))
输出结果
<class 'super'>
直接查看super的源码实现即可确认它是一个类。

此外,网络上许多文章声称super仅用于调用父类方法,这种观点是不准确的。
假设我们存在如下继承结构示例:
class A:
def __init__(self):
print("A")
class B(A):
def __init__(self):
print("B")
super().__init__()
class C(A):
def __init__(self):
print("C")
super().__init__()
class D(B, C):
def __init__(self):
print("D")
super().__init__()
D()
若依据“super仅用于调用父类方法”这一错误理解,上述代码的执行流程应被推导为:
print("D")——【调用super会先后执行B和C】——先执行B:print("B")——【调用super执行A】——
print("A")——【调用super会先后执行B和C】——后执行C:print("C")——【调用super执行A】——
print("A")
基于上述错误逻辑,理论输出结果应为:D B A C A
然而,实际运行结果并非如此。
实际执行结果
D B C A
因此,“super仅用于调用父类方法”的说法是错误的。
实际上,super的调用机制严格遵循Python的【MRO(方法解析顺序)】,在Python 3中,MRO是基于C3线性化算法实现的。
关于MRO和C3算法的详细讲解,可参考文章:https://www.jb51.net/article/224606.htm
三、super的常用使用场景
1. 当继承的多个父类包含同名方法时,可以使用super来明确指定调用哪个父类的方法。
class A:
def test(self):
print('A')
class B:
def test(self):
print('B')
class C(A, B):
def __init__(self):
super().test() # 调用A类中的test方法
super(C, self).test() # 调用A类中的test方法
super(A, self).test() # 调用B类中的test方法
C()
输出结果
A A B
2. 当子类需要调用父类方法并进行一定扩展,而不希望完全重写该方法时,使用super()可实现方法的增量修改:
举例来说,如果我们希望将list中的append方法改为中文名称添加,应如何实现?
同时,Python中list调用append方法默认返回值为None,若希望在添加元素操作成功后返回特定值返回成功,该如何操作?
首先观察直接调用原有list的执行结果。
a=list()
res=a.append(1)
print(res)
输出结果
None
可以看到,调用append方法后返回的值为None。
现在通过super进行重写,使其具有返回值,并支持通过中文名称直接调用append:
class 列表(list):
def 添加(self, *args, **kwargs):
super().append(*args, **kwargs)
return "添加成功"
x = 列表()
res = x.添加(1)
print(res)
print(x)
输出结果
添加成功 [1]
super在实际开发中应用广泛,例如在restframework中,需要重写响应结果的Response信息时,除了使用django中间件,也可以使用super重写其dispatch来实现。
以上就是Python编程super应用场景及示例解析的详细内容,更多关于Python编程super应用的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









