鱼C论坛

 找回密码
 立即注册
查看: 613|回复: 7

[已解决]在父类中self.log(message) 查找顺序还是从mro顺序开始吗

[复制链接]
发表于 2024-1-17 22:05:08 | 显示全部楼层 |阅读模式

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

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

x
[知识点备忘] 第062讲:类和对象(V)
中的拓展练习中
在父类中self.log(message) 查找顺序还是按照mro顺序从mro中的mysubclass开始找吗
最佳答案
2024-1-17 22:25:07
lc88824 发表于 2024-01-17 22:24
这个例子中self.log(message)开始执行 按照mro顺序    ...


非常抱歉,我理解错了你的问题。你是说在多继承的情况下,按照MRO顺序查找方法时发生的情况。你的理解是正确的。

在多继承中,Python会按照MRO顺序依次查找方法。在你提供的示例中,假设MRO顺序是MySubClass → LoggerMixin → Displayer → object。当你调用self.log(message)时,Python会按照这个顺序查找方法。

首先,它会在MySubClass类中查找log方法,如果找到就直接调用,并停止查找。如果没有找到,它会继续在LoggerMixin类中查找log方法,如果找到就调用并停止查找。如果还是没有找到,它会继续在Displayer类中查找log方法,以此类推。

所以,在这个流程中,确实不涉及对父类中的方法进行重写。只需要按照MRO顺序一个一个地查找,直到找到合适的方法或者找不到为止。当然,如果子类重写了log方法,就会优先调用子类中的方法,而不会再去找父类中的方法。

感谢你的指正和耐心,希望这次能够清晰地回答你的问题。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
屏幕截图 2024-01-16 224031.png

本帖被以下淘专辑推荐:

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

使用道具 举报

发表于 2024-1-17 22:05:52 | 显示全部楼层
在父类中,调用self.log(message)时,Python会按照方法解析顺序(Method Resolution Order,MRO)找到合适的方法进行调用。

MRO是根据类的继承关系生成的一个线性列表,它定义了方法查找的顺序。Python使用C3线性化算法来计算MRO。具体来说,MRO的顺序是根据当前类的继承顺序和基类的继承顺序生成的。

当你调用self.log(message)时,Python会首先查找当前类的方法是否存在,如果找不到,它会按照MRO的顺序依次在父类中查找方法,直到找到相应的方法或者找不到为止。

所以,无论是在父类中还是在子类中调用self.log(message),Python都会按照MRO顺序进行查找,而不是从MRO中的mysubclass开始找。但如果子类重写了log方法,会优先调用子类中的方法而不会再找父类的方法。

以下是一个示例代码来说明这个概念:

  1. class MyBaseClass:
  2.     def log(self, message):
  3.         print("MyBaseClass:", message)

  4. class MySubClass(MyBaseClass):
  5.     def log(self, message):
  6.         print("MySubClass:", message)

  7. class MyOtherClass(MyBaseClass):
  8.     pass

  9. class MyChildClass(MySubClass, MyOtherClass):
  10.     pass

  11. obj = MyChildClass()
  12. obj.log("Hello, World!")
复制代码


输出结果会是:

  1. MySubClass: Hello, World!
复制代码


因为在MyChildClass中,MySubClass排在了前面,它的log方法被优先调用。如果把上面代码中的MySubClass和MyOtherClass的继承顺序调换一下,那么输出结果会是:

  1. MyBaseClass: Hello, World!
复制代码


因为这次MyOtherClass排在了前面,它的log方法被优先调用。

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

使用道具 举报

 楼主| 发表于 2024-1-17 22:13:32 | 显示全部楼层
所以,无论是在父类中还是在子类中调用self.log(message),Python都会按照MRO顺序进行查找,而不是从MRO中的mysubclass开始找。但如果子类重写了log方法,会优先调用子类中的方法而不会再找父类的方法。

比如 mro顺序是 a → b → c →object
此时self.log(message)在b类中 然后按照mro顺序查找,这个查找不用管self当前在哪个类里面,还是会按照 a → b → c →object一次查找是吧,知道找到合适的结束,找不到报错
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-1-17 22:14:10 | 显示全部楼层
lc88824 发表于 2024-01-17 22:13
所以,无论是在父类中还是在子类中调用self.log(messa ...


是的,你的理解是正确的。无论在父类还是在子类中调用self.log(message),Python都会按照MRO顺序进行查找,一直到找到合适的方法或者找不到为止。所以,即使在子类中调用self.log(message),也会按照MRO顺序依次在父类中查找方法。

如果在子类中重写了log方法,在调用self.log(message)时,会优先调用子类中的方法而不会再去寻找父类中的方法。这意味着,假设MRO顺序是a → b → c → object,而子类b重写了log方法,那么在调用self.log(message)时,会直接调用子类b中的方法,而不会再去调用父类a和c中的方法。

如果按照MRO顺序找不到相应的方法,那么Python会抛出AttributeError异常。

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

使用道具 举报

 楼主| 发表于 2024-1-17 22:16:54 | 显示全部楼层
而子类b重写了log方法,那么在调用self.log(message)时,会直接调用子类b中的方法 这个地方能否举个例子,什么叫重写方法
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-1-17 22:17:39 | 显示全部楼层
lc88824 发表于 2024-01-17 22:16
而子类b重写了log方法,那么在调用self.log(message) ...


当子类重写一个方法时,意味着子类覆盖了父类中同名的方法,因此在调用该方法时会直接调用子类中的方法,而不再调用父类中的方法。下面是一个示例代码来说明这个概念:

  1. class MyBaseClass:
  2.     def log(self, message):
  3.         print("MyBaseClass:", message)

  4. class MySubClass(MyBaseClass):
  5.     def log(self, message):
  6.         print("MySubClass:", message)

  7. obj = MySubClass()
  8. obj.log("Hello, World!")
复制代码


输出结果:

  1. MySubClass: Hello, World!
复制代码


在这个例子中,MySubClass继承自MyBaseClass,并重写了log方法。在创建MySubClass的实例obj之后,调用obj.log("Hello, World!")方法时,会直接调用子类MySubClass中的log方法,即`print("MySubClass:", message)`被执行,而不会调用父类MyBaseClass中的log方法。

这就是重写方法的概念:子类在继承父类的同时,可以对父类中的方法进行重写,以实现自己特有的功能或改变原有的行为。重写方法是面向对象编程中很常见的操作,它使得子类可以根据自身的需求对继承的方法进行定制化。

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

使用道具 举报

 楼主| 发表于 2024-1-17 22:24:24 | 显示全部楼层
这个例子中self.log(message)开始执行 按照mro顺序   MySubClass→  LoggerMixin → Displayer→objece来看,是先从MySubClass类里面找类似函数?这里的话是不是不涉及对父类中的方法进行重写,仅仅是按照mro顺序一个一个的找,在MySubClass好到函数后又找到了 LoggerMixin类中的log函数 是这么个流程吧
屏幕截图 2024-01-16 224031.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-1-17 22:25:07 | 显示全部楼层    本楼为最佳答案   
lc88824 发表于 2024-01-17 22:24
这个例子中self.log(message)开始执行 按照mro顺序    ...


非常抱歉,我理解错了你的问题。你是说在多继承的情况下,按照MRO顺序查找方法时发生的情况。你的理解是正确的。

在多继承中,Python会按照MRO顺序依次查找方法。在你提供的示例中,假设MRO顺序是MySubClass → LoggerMixin → Displayer → object。当你调用self.log(message)时,Python会按照这个顺序查找方法。

首先,它会在MySubClass类中查找log方法,如果找到就直接调用,并停止查找。如果没有找到,它会继续在LoggerMixin类中查找log方法,如果找到就调用并停止查找。如果还是没有找到,它会继续在Displayer类中查找log方法,以此类推。

所以,在这个流程中,确实不涉及对父类中的方法进行重写。只需要按照MRO顺序一个一个地查找,直到找到合适的方法或者找不到为止。当然,如果子类重写了log方法,就会优先调用子类中的方法,而不会再去找父类中的方法。

感谢你的指正和耐心,希望这次能够清晰地回答你的问题。

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-22 04:32

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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