深入解析Python多重继承中super()的调用机制与MRO

星野
星野
发布时间:2026-10-13| 6人浏览过
原创

本文深入探讨Python中super()在多重继承下的工作原理。通过对比简单继承与复杂多重继承,揭示直接调用父类方法的局限性。重点解析MRO(方法解析顺序)的C3线性化算法,阐明super()如何沿MRO链查找并调用下一个类的方法,从而避免重复调用和代码耦合,提供多重继承的最佳实践方案。

Python多重继承中super()的基本概念

当类之间的继承结构较为简单时,使用super()函数通常不会遇到太多困难。


class A(object):
 def __init__(self):
  print('a')
 
 
class B(A):
 def __init__(self):
  super(B, self).__init__()
  print('b')
 
b = B()

以下是简单的输出结果示例:


a
b

多重继承下的调用挑战

然而,当一个类继承自多个父类时,情况会变得复杂。请参考以下代码示例:


class A(object):
 def __init__(self):
  print('a')
 
 
class B(object):
 def __init__(self):
  print('b')
  
  
class C(A, B):
 def __init__(self):
  super(C, self).__init__()
  print('c')
 
c = C()

乍看之下,结果似乎很简单,预期输出应该是a和c。确实如此!但如果C类希望同时调用A类和B类的__init__()方法,该如何处理呢?

有人可能会提出,直接显式调用父类的__init__()方法不就可以了吗?


class A(object):
 def __init__(self):
  print('a')
 
 
class B(object):
 def __init__(self):
  print('b')
  
  
class C(A, B):
 def __init__(self):
  A.__init__()
  B.__init__()
  print('c')
 
c = C()

虽然效果相同,但这并非最佳方案。因为这种方式没有使用super(),而super()的一个重要优势是:当父类名称发生更改时,子类无需修改调用逻辑,从而提高了代码的可维护性。

使用super()的完美解决方案

下面提供一种更完善的解决方案:


class A(object):
 def __init__(self):
  super(A, self).__init__()
  print('a')
 
 
class B(object):
 def __init__(self):
  super(B, self).__init__()
  print('b')
 
 
class C(A, B):
 def __init__(self):
  super(C, self).__init__()
  print('c')
 
print(C.mro())
c = C()

代码中包含了print(C.mro()),在实际生产环境中可以省略。这里保留它是为了后续解释其作用。

运行上述代码后的输出结果如下:


[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <type 'object'>]
b
a
c

深入理解MRO与调用顺序

请注意,输出顺序是b, a, c,而不是按类定义顺序的a, b, c。这是为什么呢?

这需要结合前面mro()的输出结果来解释。MRO全称Method Resolution Order(方法解析顺序),用于定义继承方法的具体调用顺序。自Python 2.3版本起,MRO采用C3线性化算法(区别于传统的深度优先或广度优先),其生成的顺序为:


[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <type 'object'>]

每次调用super()时,它实际上是在MRO列表中查找当前类的下一个类。在上述示例中:super(C, self)指向MRO列表中的下一个类A,因此调用A的__init__();在A的__init__()中再次调用super(),此时MRO列表中的下一个类是B,因此调用B的__init__();B的__init__()中调用super()指向object,而object的__init__()不执行任何操作;随后控制流返回B,执行print('b');接着返回A,执行print('a');最后返回C,执行print('c')。

这里需要再次强调:super(type, obj).func()调用的是obj实例在MRO列表中下一个父类的func()方法,而不是type类本身的父类中的func()(这是第一个示例可能带来的误解)。

以上关于解决Python super()在多重继承中调用函数问题的内容,就是小编分享给大家的全部知识。希望能对大家有所帮助,也欢迎大家继续支持本站。

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。