Python多重继承与菱形继承详解:MRO机制与super()用法

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

本文深入解析Python中的多重继承与菱形继承问题,通过实例展示经典调用顺序导致的父类重复执行现象。重点介绍MRO(方法解析顺序)及C3算法如何确保每个类仅被调用一次,并演示如何利用super()函数优化代码结构,实现广度优先的清晰调用链,适用于Python3新式类场景。

Python多重继承基础

继承是面向对象编程的核心机制之一,它允许子类扩展父类的功能。在Python中,一个类可以同时继承多个父类,这种特性被称为多重继承(Multiple Inheritance)。

语法

class SubclassName(BaseClass1, BaseClass2, BaseClass3, ...): pass

菱形继承问题解析

菱形继承

当多层继承与多重继承结合使用时,会形成复杂的继承关系网络。在这种结构下,最典型的场景便是菱形继承。

其结构特征如下图所示。mark

在此结构中,方法的调用顺序成为关键问题,具体遵循哪种路径呢?

  • D->B->A->C(深度优先)
  • D->B->C->A(广度优先)

接下来我们将通过具体示例来解答这一疑问。

通过以下代码示例进行观察:


class A():
 def __init__(self):
  print('init A...')
  print('end A...')

class B(A):
 def __init__(self):
  print('init B...')
  A.__init__(self)
  print('end B...')

class C(A):
 def __init__(self):
  print('init C...')
  A.__init__(self)
  print('end C...')

class D(B, C):
 def __init__(self):
  print('init D...')
  B.__init__(self)
  C.__init__(self)
  print('end D...')

if __name__ == '__main__':
 D()

输出结果

init D... init B... init A... end A... end B... init C... init A... end A... end C... end D...

从上述输出结果可以看出,实际的调用顺序为:D->B->A->C->A。由于B和C都继承自A,导致父类A的方法被执行了两次。显然,顶层父类A的重复调用是不必要的,造成了资源浪费。

MRO机制与C3算法

解决这一问题的核心在于MRO(Method Resolution Order,方法解析顺序)。MRO主要用于在多重继承场景中确定属性或方法的查找来源。Python采用了一种名为C3的算法来计算MRO,其核心思想是在确保同一类只被搜寻一次的前提下,结合广度优先和从左到右的原则来查找所需的属性和方法。

那么,如何避免顶层父类中的某个方法被多次调用呢?此时需要引入super()函数。super()本质上是一个类,内部记录了MRO信息。由于C3算法保证了同一个类在MRO序列中只会出现一次,因此利用super()可以确保顶层父类的方法仅被执行一次。基于此,上述代码可以优化为:


class A():
 def __init__(self):
  print('init A...')
  print('end A...')

class B(A):
 def __init__(self):
  print('init B...')
  super(B, self).__init__()
  print('end B...')

class C(A):
 def __init__(self):
  print('init C...')
  super(C, self).__init__()
  print('end C...')

class D(B, C):
 def __init__(self):
  print('init D...')
  super(D, self).__init__()
  print('end D...')

if __name__ == '__main__':
 D()

输出结果:

init D... init B... init C... init A... end A... end C... end B... end D...

从优化后的输出结果可以看出,此时的调用顺序变为D->B->C->A。这表明系统采用了广度优先的遍历方式,避免了重复调用。

经典类与新式类的区别

补充内容

Python中的类主要分为两种:经典类和新式类。虽然两者都支持多继承,但它们的继承顺序机制不同。

新式类:指从object类继承而来的类(例如:class A(object))。新式类采用广度优先搜索的方式进行继承,即先进行水平搜索,再进行向上搜索。

经典类:指不从object类继承而来的类(例如:class A())。经典类采用深度优先搜索的方式进行继承,即先深入继承树的左侧,返回后再查找右侧。

在Python 2.x版本中,类分为经典类和新式类两种;而在Python 3.x版本中,所有类均默认为新式类。

总结

以上所述是小编给大家介绍的Python多重继承之菱形继承的实例详解,希望对大家有所帮助!

相关标签:

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

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 算法库。