Python中super()的理解以及应用场景实例
本文深入解析Python中super()的本质,指出其并非简单调用父类方法,而是遵循MRO(方法解析顺序)和C3算法。通过多继承示例澄清常见误区,并展示super在指定父类方法及增量扩展方法(如重写list append)中的实际应用,帮助开发者正确理解和使用super。
一、前言
近期有读者反馈,网络上关于super的教程往往晦涩难懂,导致理解困难。因此,本文旨在基于个人理解,对super机制进行通俗易懂的讲解。
二、什么是super
首先需要明确,super本身是一个类,它既不是普通的方法,也不是Python的关键字。
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算法的详细原理,可参考文章:http://kaiyuan.me/2016/04/27/C3_linearization/
三、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()内容,请搜索本站历史文章或继续浏览后续文章。感谢大家的支持!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













