鱼C论坛

 找回密码
 立即注册
查看: 131|回复: 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

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

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

在 Python 中,当我们调用一个方法时,解释器会根据MRO顺序来查找该方法。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()

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

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

根据类 `D` 的 MRO 顺序,我们可以通过 `D.__mro__` 来查看:
>>> D.__mro__
(<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` 方法。所以答案是:
A ping~
B pong~

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

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

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-4-2 02:39

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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