python理解不了这2个例子的调用顺序
>>> class A:... def say_hi(self):
... print("Hi from A~")
...
... def say(self):
... super().say_hi()
...
>>> class B1(A):
... def say_hi(self):
... print("Hi from B1~")
...
... def say(self):
... super().say()
...
>>> class B2:
... def say_hi(self):
... print("Hi from B2~")
...
... def say(self):
... super().say()
...
>>> class C(B1, B2):
... def say(self):
... super().say()
...
>>> c = C()
>>> c.say()
# 请问这里会打印什么内容?
>>> c = C()
>>> c.say()
Hi from B2~
不能理解,为什么只显示了Hi from B2~。
我的理解,应该是先调用B1,B1得去调用A,然后就调出了Hi from A~,应该没有B2什么事才对呀??
>>> class A:
... def say(self):
... print("FishA")
...
>>> class B:
... def say(self):
... print("FishB")
...
>>> class C(A):
... def say(self):
... super().say()
... print("FishC")
...
>>> class D(B):
... def say(self):
... super().say()
... print("FishD")
...
>>> class E(C, D):
... def say(self):
... super().say()
... print("FishE")
...
>>> e = E()
>>> e.say()
# 请问这里会打印什么内容?
>>> e = E()
>>> e.say()
FishA
FishC
FishE
这个例子,按我的理解,应该是先打印C,C从A调用,所以调出FishA,然后调用完C后就调用D,D要从父类B调用,所以调用出FishB。
实在不理解怎么出这个结果的。 你好!这个问题涉及到 Python 中多继承的 super() 和 MRO(方法解析顺序)机制,确实容易让人困惑。我们来一步步分析。
核心要点:
[*] super() 并不是直接调用“父类”的方法,而是按照 MRO 顺序调用“下一个”类的方法。
[*] MRO 顺序可以通过 类名.__mro__ 查看。
第一个例子分析:
class A:
def say_hi(self):
print("Hi from A~")
def say(self):
super().say_hi()# 注意:这里调用的是 say_hi,不是 say
class B1(A):
def say_hi(self):
print("Hi from B1~")
def say(self):
super().say()# 调用 MRO 中下一个类的 say 方法
class B2:
def say_hi(self):
print("Hi from B2~")
def say(self):
super().say()# 如果找不到,最终会调用 object 的方法(可能出错)
class C(B1, B2):
def say(self):
super().say()# 调用 MRO 中下一个类的 say 方法
先查看 C 的 MRO:
print(C.__mro__)
输出: (<class '__main__.C'>, <class '__main__.B1'>, <class '__main__.A'>, <class '__main__.B2'>, <class 'object'>)
调用 c.say() 的完整流程:
[*] C.say() 中的 super().say() 根据 MRO 找到下一个类 B1。
[*] B1.say() 中的 super().say() 找到下一个类 A。
[*] A.say() 中的 super().say_hi() 找到下一个类 B2(因为 MRO 中 A 之后是 B2)。
[*] B2.say_hi() 被调用,打印 Hi from B2~。
因此,最终只打印了 Hi from B2~。
第二个例子分析:
class A:
def say(self):
print("FishA")
class B:
def say(self):
print("FishB")
class C(A):
def say(self):
super().say()# 调用 A.say()
print("FishC")
class D(B):
def say(self):
super().say()# 调用 B.say()
print("FishD")
class E(C, D):
def say(self):
super().say()# 调用 MRO 中下一个类的 say 方法
print("FishE")
先查看 E 的 MRO:
print(E.__mro__)
输出: (<class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class '__main__.D'>, <class '__main__.B'>, <class 'object'>)
调用 e.say() 的完整流程:
[*] E.say() 中的 super().say() 根据 MRO 找到下一个类 C。
[*] C.say() 中的 super().say() 找到下一个类 A。
[*] A.say() 被调用,打印 FishA,然后返回。
[*] C.say() 继续执行,打印 FishC,然后返回。
[*] E.say() 继续执行,打印 FishE。
注意:由于 A.say() 中没有调用 super(),所以调用链在此终止,不会继续调用 D 或 B 的方法。因此最终输出三行。
总结:
[*] MRO 顺序决定了 super() 的查找路径。
[*] 调用链会在某个方法中没有 super() 时终止。
[*] 建议在实际代码中,如果设计多继承,确保每个类中的相关方法都通过 super() 正确协作。
希望这个解释能帮助你理解!如果还有疑问,欢迎继续讨论。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页:
[1]