在父类中self.log(message) 查找顺序还是从mro顺序开始吗
[知识点备忘] 第062讲:类和对象(V)中的拓展练习中
在父类中self.log(message) 查找顺序还是按照mro顺序从mro中的mysubclass开始找吗 在父类中,调用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方法,会优先调用子类中的方法而不会再找父类的方法。
以下是一个示例代码来说明这个概念:
class MyBaseClass:
def log(self, message):
print("MyBaseClass:", message)
class MySubClass(MyBaseClass):
def log(self, message):
print("MySubClass:", message)
class MyOtherClass(MyBaseClass):
pass
class MyChildClass(MySubClass, MyOtherClass):
pass
obj = MyChildClass()
obj.log("Hello, World!")
输出结果会是:
MySubClass: Hello, World!
因为在MyChildClass中,MySubClass排在了前面,它的log方法被优先调用。如果把上面代码中的MySubClass和MyOtherClass的继承顺序调换一下,那么输出结果会是:
MyBaseClass: Hello, World!
因为这次MyOtherClass排在了前面,它的log方法被优先调用。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 所以,无论是在父类中还是在子类中调用self.log(message),Python都会按照MRO顺序进行查找,而不是从MRO中的mysubclass开始找。但如果子类重写了log方法,会优先调用子类中的方法而不会再找父类的方法。
比如 mro顺序是 a → b → c →object
此时self.log(message)在b类中 然后按照mro顺序查找,这个查找不用管self当前在哪个类里面,还是会按照 a → b → c →object一次查找是吧,知道找到合适的结束,找不到报错 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 小助理,如未能正确解答您的问题,请继续追问。 而子类b重写了log方法,那么在调用self.log(message)时,会直接调用子类b中的方法 这个地方能否举个例子,什么叫重写方法 lc88824 发表于 2024-01-17 22:16
而子类b重写了log方法,那么在调用self.log(message) ...
当子类重写一个方法时,意味着子类覆盖了父类中同名的方法,因此在调用该方法时会直接调用子类中的方法,而不再调用父类中的方法。下面是一个示例代码来说明这个概念:
class MyBaseClass:
def log(self, message):
print("MyBaseClass:", message)
class MySubClass(MyBaseClass):
def log(self, message):
print("MySubClass:", message)
obj = MySubClass()
obj.log("Hello, World!")
输出结果:
MySubClass: Hello, World!
在这个例子中,MySubClass继承自MyBaseClass,并重写了log方法。在创建MySubClass的实例obj之后,调用obj.log("Hello, World!")方法时,会直接调用子类MySubClass中的log方法,即`print("MySubClass:", message)`被执行,而不会调用父类MyBaseClass中的log方法。
这就是重写方法的概念:子类在继承父类的同时,可以对父类中的方法进行重写,以实现自己特有的功能或改变原有的行为。重写方法是面向对象编程中很常见的操作,它使得子类可以根据自身的需求对继承的方法进行定制化。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 这个例子中self.log(message)开始执行 按照mro顺序 MySubClass→LoggerMixin → Displayer→objece来看,是先从MySubClass类里面找类似函数?这里的话是不是不涉及对父类中的方法进行重写,仅仅是按照mro顺序一个一个的找,在MySubClass好到函数后又找到了 LoggerMixin类中的log函数 是这么个流程吧 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 小助理,如未能正确解答您的问题,请继续追问。
页:
[1]