方法解析顺序
本课属于 Coddy Python 学习旅程的“面向对象编程”单元。第 21 课,共 64 课。
方法解析顺序(MRO)是当多个类具有相同的方法名时,Python 查找方法所使用的顺序。
下面是一个示例,其中多个类具有同一个方法:
class A:
def method(self):
return "Method from A"
class B:
def method(self):
return "Method from B"
class C(A, B):
pass使用 __mro__ 查看 MRO:
print(C.__mro__)输出:
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)__mro__ 属性是一个元组,包含解析顺序中的所有类。第一个元素(__mro__[0])始终是类本身(C),后面依次是从左到右的父类(A,然后是 B),最后是内置的 object 类。
创建一个对象并调用该方法:
c = C()
print(c.method())输出:
Method from APython 先在类 A 中找到了这个方法(在 MRO 中的索引为 1),所以使用了它。
更改继承顺序,看看有什么不同:
class D(B, A): # 现在 B 排在 A 前面
pass
print(D.__mro__)
d = D()
print(d.method())输出:
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
Method from B现在,Python 会先找到 B 的方法,因为在继承列表中,B 排在 A 前面。你可以使用索引访问 MRO 中的特定类:D.__mro__[0] 是 D 本身,D.__mro__[1] 是 B,D.__mro__[2] 是 A。
你也可以使用 mro() 方法:
print(C.mro())虽然 mro() 和 __mro__ 提供相同的类序列,但它们的类型不同:__mro__ 返回一个 元组,而 mro() 返回一个 列表。
要点:Python 会按 MRO 顺序查找方法,先查类本身(索引 0),再按类定义中从左到右的顺序查找父类(索引 1、2 等)。找到的第一个方法会被使用。
挑战
中等在这个挑战中,你将实现一个类层次结构。
你需要编辑以下文件:
device.py:实现基类Devicescreen.py:实现继承自Device的Screen类computer.py:实现继承自Device的Computer类laptop.py:实现使用多重继承的Laptop类driver.py:实现测试用例,验证你的实现是否正确
每个文件都包含详细的 TODO 注释,会逐步指导你完成实现。
亲手试试
# TODO: 导入所有需要的类
# from device import Device
# from screen import Screen
# from computer import Computer
# from laptop import Laptop
def explain_mro(class_name):
# TODO: 打印给定类的 MRO(方法解析顺序)
# TODO: 格式为 "MRO for [class name]:"(注意:冒号后没有空格)
# TODO: 用 class_name.__name__ 获取类名
# TODO: 用 class_name.__mro__ 获取 MRO 元组
# TODO: 将 MRO 中的每个类名分别打印在单独一行
# TODO: 创建该类的一个实例
# TODO: 在实例上调用 power_on() 并保存结果
# TODO: 输出:"Power on result: [result]"
# TODO: 输出一个空行,方便阅读
pass
# 测试你的代码
# TODO: 分别用 Device、Screen、Computer 和 Laptop 类调用 explain_mro()
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Python 在线编译器