|
|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
>>> 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:
输出: (<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:
输出: (<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 小助理,如未能正确解答您的问题,请继续追问。
|
|