鱼C论坛

 找回密码
 立即注册
查看: 195|回复: 1

关于类和对象MRO继承顺序的问题

[复制链接]
发表于 2025-2-23 19:59:49 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
我在学习小甲鱼老师的在类和对象中讲解MRO顺序的课程对MRO顺序产生了困惑,练习题如下:

>>> class A:
...     def ping(self):
...         print("A ping~")
...
>>> class B(A):
...     def pong(self):
...         print("B pong~")
...
>>> class C(A):
...     def pong(self):
...         print("C pong~")
...
>>> class D(B, C):
...     def pingpong(self):
...         self.ping()
...         self.pong()
...
>>> d = D()
>>> d.pingpong()
>>> # 请问这里会打印什么内容?

答案是:
>>> d.pingpong()
A ping~
B pong~

我的困惑是按照MRO继承顺序,如果相关函数在B类和C类中均出现,那么是否会在B类中先执行,然后再到C类中去执行?还是只在B类中去执行,而不会去C类中再执行?

这道题我的理解是对于ping()方法,由于D类本身中没有,按照MRO继承顺序应该先去B类中找,然而B类中也没有,再去其父类A中去找,此时A类中有ping()方法,故执行相关语句(即打印"A ping~").我的困惑是之后会不会再去类C中找ping方法?我的理解流程如下:

首先是去查找ping()函数
ping()方法查找流程:  实例对象d  类D  类B  类A 类C
其次再去找pong()函数
pong()方法查找流程:  实例对象d  类D  类B  类A 类C

麻烦大佬帮忙指点一下我的理解是否有误,谢谢!

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2025-2-23 19:59:58 | 显示全部楼层
你对MRO(Method Resolution Order)的理解已经比较准确了。下面是具体的解释。

在 Python 中,当我们调用一个方法时,解释器会根据MRO顺序来查找该方法。MRO是确定类的继承层次和方法解析优先级的规则。MRO的顺序是从当前类开始,按照继承链从左到右依次搜索。

对于你提到的例子:

  1. class A:
  2.     def ping(self):
  3.         print("A ping~")

  4. class B(A):
  5.     def pong(self):
  6.         print("B pong~")

  7. class C(A):
  8.     def pong(self):
  9.         print("C pong~")

  10. class D(B, C):
  11.     def pingpong(self):
  12.         self.ping()
  13.         self.pong()

  14. d = D()
  15. d.pingpong()
复制代码


这里调用的方法 `pingpong` 会按照以下顺序执行:

1. `self.ping()`
2. `self.pong()`

根据类 `D` 的 MRO 顺序,我们可以通过 `D.__mro__` 来查看:

  1. >>> D.__mro__
  2. (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
复制代码


这意味着 `D` 类的MRO顺序是:

1. D
2. B
3. C
4. A
5. object

因此,对于 `self.ping()` 的查找顺序是:
- `D` -> `B` -> `A`

由于 `A` 类中定义了 `ping` 方法,所以会在 `A` 类中找到并执行 `ping` 方法,输出 "A ping~"。

对于 `self.pong()` 的查找顺序是:
- `D` -> `B`

因为 `B` 类中定义了 `pong` 方法,所以会在 `B` 类中找到并执行 `pong` 方法,输出 "B pong~"。

由于 `B` 类中已经有 `pong` 方法,不会再继续查找 `C` 类中的 `pong` 方法。所以答案是:
  1. A ping~
  2. B pong~
复制代码


你的理解基本正确,只是不需要再去 `C` 类中查找 `ping` 方法了,因为已经在 `A` 类中找到了同名的方法。同理,对于 `pong` 方法,在 `B` 类中找到之后就不会再往下查找。

所以,在 MRO 查找到第一个匹配方法后,就停止继续查找了,不会在其他类中再查找同名方法。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-5-6 00:07

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表