鱼C论坛

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

钻石继承课程中调整未绑定父类顺序的困惑

[复制链接]
发表于 2025-4-6 15:25:05 | 显示全部楼层 |阅读模式

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

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

x
小甲鱼老师在super()函数扩展阅读中有以下例题:
class A:
    def say(self):
        print("FishA")

class B:
    def say(self):
        print("FishB")
        
class C(A):
    def say(self):
        A.say(self)
        print("FishC")
        
class D(B):
    def say(self):
        B.say(self)
        print("FishD")

class E(C, D):
    def say(self):
        D.say(self)
        C.say(self)
        print("FishE")

e = E()
e.say()

代码执行结果如下:
FishA
FishB
FishC
FishD
FishE

我如果把定义类E中的D.say(self)和E.say(self)调换一下顺序,如下:
class A:
    def say(self):
        print("FishA")

class B:
    def say(self):
        print("FishB")
        
class C(A):
    def say(self):
        A.say(self)
        print("FishC")
        
class D(B):
    def say(self):
        B.say(self)
        print("FishD")

class E(C, D):
    def say(self):
       C.say(self)
        D.say(self)

        print("FishE")

e = E()
e.say()
则执行结果变成:
FishA
FishC
FishB
FishD
FishE

烦请大神指点这是为什么?
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2025-4-6 15:27:17 | 显示全部楼层
问题解答:显式调用父类方法与继承顺序的关系


你的困惑源于显式调用父类方法(如 C.say(self))与继承顺序(MRO)的关系。以下是详细解释:

  • 显式调用父类方法的顺序决定了执行流
    在类 Esay 方法中,你直接调用了 C.say(self)D.say(self)。这两个方法的执行顺序完全由代码中的调用顺序决定,与继承链(MRO)无关。调换顺序后,输出顺序自然改变。
  • 每个父类方法的内部逻辑固定
    以第一个代码为例:

    1. class E(C, D):
    2.     def say(self):
    3.         D.say(self)  # 先执行D的逻辑
    4.         C.say(self)  # 再执行C的逻辑
    5.         print("FishE")
    复制代码

    执行流程:
    1. D.say() → 调用 B.say()(输出 FishB),再输出 FishD
    2. C.say() → 调用 A.say()(输出 FishA),再输出 FishC
    3. 最终输出顺序:FishB → FishD → FishA → FishC → FishE

    但用户提供的第一次输出描述有误,实际结果应为上述顺序。你的第二次代码调换后:

    1. class E(C, D):
    2.     def say(self):
    3.         C.say(self)  # 先执行C的逻辑
    4.         D.say(self)  # 再执行D的逻辑
    5.         print("FishE")
    复制代码

    输出顺序变为:FishA → FishC → FishB → FishD → FishE
  • MRO 仅在隐式调用(如 super())时生效
    如果使用 super(),继承顺序 E(C, D) 会通过 MRO 决定调用顺序。但你的代码显式指定了父类方法,绕过了 MRO 机制。


总结:  
显式调用父类方法时(如 C.say(self)),执行顺序完全由代码顺序控制。调换调用顺序会直接改变输出结果,与继承链无关。

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-5-5 20:28

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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