练习多重继承
Python 允许一个类从多个父类继承。这被称为多重继承 (multiple inheritance)。它可以成为混合来自不同来源的功能的强大工具,但它也带来了复杂性,特别是在它们具有相同名称时,Python 如何决定使用哪个父类的方法。
这种搜索顺序被称为方法解析顺序 (Method Resolution Order, MRO)。Python 使用一种称为 C3 线性化 (C3 linearization) 的算法来确定一致且可预测的 MRO。
让我们用一个新的例子来探索这一点。从文件浏览器中打开 multiple_inheritance.py 文件,并添加以下代码:
## File: multiple_inheritance.py
class ParentA:
def speak(self):
print("Speaking from ParentA")
def common_method(self):
print("ParentA's common method")
class ParentB:
def speak(self):
print("Speaking from ParentB")
def common_method(self):
print("ParentB's common method")
## Child 继承自 A,然后是 B
class Child_AB(ParentA, ParentB):
pass
## Child 继承自 B,然后是 A
class Child_BA(ParentB, ParentA):
def common_method(self):
print("Child_BA's own common method")
if __name__ == "__main__":
child1 = Child_AB()
child2 = Child_BA()
print("--- Investigating Child_AB (ParentA, ParentB) ---")
child1.speak()
child1.common_method()
## .mro() 方法显示了方法解析顺序
print("MRO for Child_AB:", [c.__name__ for c in Child_AB.mro()])
print("\n--- Investigating Child_BA (ParentB, ParentA) ---")
child2.speak()
child2.common_method()
print("MRO for Child_BA:", [c.__name__ for c in Child_BA.mro()])
保存文件。在这里,Child_AB 继承自 ParentA,然后是 ParentB。Child_BA 则以相反的顺序继承。当调用一个方法时,Python 会按照 MRO 指定的顺序进行查找。
从终端运行脚本:
python multiple_inheritance.py
你将看到以下输出:
--- Investigating Child_AB (ParentA, ParentB) ---
Speaking from ParentA
ParentA's common method
MRO for Child_AB: ['Child_AB', 'ParentA', 'ParentB', 'object']
--- Investigating Child_BA (ParentB, ParentA) ---
Speaking from ParentB
Child_BA's own common method
MRO for Child_BA: ['Child_BA', 'ParentB', 'ParentA', 'object']
从输出中,你可以观察到:
child1.speak() 调用了 ParentA 中的方法,因为 ParentA 在 Child_AB 的 MRO 中排在前面。
child2.speak() 调用了 ParentB 中的方法,因为 ParentB 在 Child_BA 的 MRO 中排在前面。
child2.common_method() 调用了在 Child_BA 中直接定义的那一个版本,因为 Python 首先在那里找到了它,然后再检查父类。
理解 MRO 对于预测多重继承场景下的行为至关重要。