继承 是面向对象编程中的一个特性,允许类继承另一个类的属性和方法。在 Python 中,你可以实现不同类型的继承,比如单继承、多继承和多层继承。本章详细介绍了多重继承。
什么是多重继承?
多重继承是一种继承方式,其中单个类可以继承多个父类的属性和方法。当你想把多个类的功能整合到一个类里时,这可以用。下图展示了多重继承 −

多重继承的例子
在下面的例子中,子类继承了父类和母类 -
class Father:
def skill1(self):
print("Father's skill: Gardening")
class Mother:
def skill2(self):
print("Mother's skill: Cooking")
class Child(Father, Mother):
pass
c = Child()
c.skill1()
c.skill2()
上述代码的输出为−
Father's skill: Gardening
Mother's skill: Cooking
解释: 在这个例子中,子 类可以同时访问其父类的 skill1() 和 skill2() 方法。当我们创建 Child 实例并调用 skill1() 时,它执行的是 Father 类的方法。同样,当我们调用 skill2() 时,它执行的是母类的方法。
但是,如果两个父类都有同名的方法,会发生什么?谁会被处决?这就是方法分辨率次序(MRO)发挥作用的地方。
多重继承的方法解析顺序
如果同名方法在多个父类中定义,Python 会遵循特定的顺序来决定执行哪个方法。该命令被称为**方法解析令(MRO)。**该阶数由C3线性化算法(也称为MRO)确定。MRO命令如下所示。
- 首先,Python 在子类中查找方法。
- 如果找不到,它会按列表的顺序搜索父类。
- 直到找到方法或搜索所有类为止。
多重继承最核心的问题是:当多个父类有同名方法时,子类调用该方法会优先执行哪个父类的? Python 通过MRO(Method Resolution Order,方法解析顺序) 来解决这个问题,遵循 "从左到右、深度优先" 的原则(Python3 中是 C3 算法,本质是优化后的深度优先)。
你可以用mro() 方法或**mro**属性检查对象的MRO。例如−
print(Child.mro())
Output:
[<class '__main__.Child'>, <class '__main__.Father'>, <class '__main__.Mother'>,
<class 'object'>]
示例
在以下示例中,Child 类继承了 Father 和 Mother 类的 skill() 方法,但调用的是 mother's 方法。
python
class Father:
def skill(self):
print("Father's skill: Gardening")
class Mother:
def skill(self):
print("Mother's skill: Cooking")
class Child(Father, Mother):
pass
c = Child()
c.skill()
解释: 当技能方法在子类实例c中被调用时,它首先会在子类中查找该方法。由于子类没有技能方法,它会按父类排序(父类,然后是母类)搜索父类,并执行第一个找到的。
上述代码的输出为−
Father's skill: Gardening
在多重继承中使用 super()
super() 函数被子类用于调用父类的方法。如果你在多重继承情况下的方法中使用 super(),它会严格按照 MRO 命令来决定调用哪个方法。
示例
在这个例子中,我们有一个包含四个类的类层级结构:A、B、C 和 D。类 D 继承自 B 和 C,证明了多重继承。
python
class A:
def show(self):
print("Class A")
class B(A):
def show(self):
print("Class B")
super().show()
class C(A):
def show(self):
print("Class C")
super().show()
class D(B, C):
def show(self):
print("Class D")
super().show()
d = D()
d.show()
上述代码的输出为−
Class D
Class B
Class C
Class A
**解释:**D类的MRO为[D, B, C, A, 对象]。这意味着当某个方法在D实例上被调用时,Python会先在D中寻找该方法,然后是B,再是C,最后是A。因此,"D类"、"B类"、"C类"和"A类"将按该顺序印刷。
多重继承中的钻石问题
钻石问题是多重继承中常见的问题。当两个父类继承同一个基类,而子类继承两个父类时,就会出现这种情况。下图展示了这个场景:

钻石问题导致在继承基类时,该调用哪个方法产生混淆。Python 通过遵循我们之前讨论过的方法解析顺序(mro)来解决这个问题。让我们看看钻石问题的例子 −
示例
下面的代码演示了钻石问题以及Python如何通过MRO解决 −
python
class A:
def show(self):
print("Class A")
class B(A):
def show(self):
print("Class B")
class C(A):
def show(self):
print("Class C")
class D(B, C):
pass
d = D()
d.show()
上述代码的输出为−
Class B
**解释:**D类的MRO命令为[D, B, C, A]。所以,当调用 d.show() 时,它首先在类 D 里查找,但那里没有 show 函数,于是它会去 class B,找到 show 函数并执行它。
多重继承的坑与最佳实践
1. 避免的问题
- 钻石继承(菱形继承):多个父类最终继承自同一个基类,可能导致重复调用或属性冲突(Python3 的 C3 算法已解决,但仍需谨慎)。
- 代码可读性差:过多父类会让代码逻辑混乱,难以维护。
2. 最佳实践
- 尽量少用多重继承:能用单一继承 + 组合 / 接口实现的,就不用多重继承。
- 使用 Mixin 模式:将通用功能封装成 Mixin 类(仅包含方法,无属性),作为辅助继承,主逻辑仍用单一继承。
python
# Mixin类:仅提供通用功能
class SwimMixin:
def swim(self):
print("会游泳")
# 主父类
class Person:
def eat(self):
print("会吃饭")
# 子类:主继承Person,辅助继承SwimMixin
class Student(Person, SwimMixin):
pass
stu = Student()
stu.eat() # 输出:会吃饭
stu.swim() # 输出:会游泳
多重继承的利弊
多重继承有若干优缺点 -
| 优点 | 缺点 |
|---|---|
| 提升代码模块化和可复用性。 | 增加了复杂度,可能导致模糊性。 |
| 允许将多个类别的功能组合在一起。 | 这可能导致钻石问题。 |
| 可以创建复杂的现实关系 | 调试和维护更难。 |
多重继承是一种面向对象编程的概念,其中来自多个父类的方法可以被子类继承。我们讨论了 Python 如何利用方法解析顺序(MRO)处理多重继承,以及如何使用 super() 函数。钻石问题在多重继承中很常见,但 Python 通过 MRO 解决了这个问题。多重继承的主要缺点是让职业层级结构更复杂且更难理解。
结论
- Python 支持多重继承,子类可继承多个父类的属性和方法,写法为
class 子类(父类1, 父类2, ...)。 - 同名方法的执行顺序遵循 MRO 规则,可通过
__mro__查看,默认优先执行左侧父类的方法。 - 实际开发中应尽量少用多重继承,推荐 Mixin 模式(辅助功能 + 主继承),保证代码可读性和可维护性。