|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
- class A:
- def say(self):
- print("FishA")
- class B(A):
- def say(self):
- super().say()
- print("FishB")
- class C(A):
- def say(self):
- super().say()
- print("FishC")
- class D(B,C):
- def say(self):
- B.say(self)
- C.say(self)
- print('FishD')
- d = D()
- d.say()
- print(D.__mro__)
- FishA
- FishC
- FishB
- FishA
- FishC
- FishD
- (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
复制代码
请指点分析一下, 上面这部分代码的输出顺序为什么是这样呢?
Python 的多继承中,一个类可以继承多个类,当多个父类中有相同的方法时,会按照一定的顺序来查找这个方法,这就是所谓的方法解析顺序(Method Resolution Order,MRO)。Python 的 MRO 是基于 C3 线性化算法的,保证所有的子类总是会先于父类被检查,有些父类又会根据其在列表中的顺序被检查。
具体到这段代码,我们可以先分析一下 MRO 顺序。当你执行 D.__mro__ 时,输出的元组就是其 MRO,即 (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>) 。这意味着,Python 在查找 D 类的方法时,会按照 D -> B -> C -> A -> object 的顺序去查找。
然后看 D 类中的 say 方法:
- def say(self):
- B.say(self)
- C.say(self)
- print('FishD')
复制代码
D.say 方法先调用了 B.say 方法,然后调用了 C.say 方法,最后打印 'FishD'。因此, B.say(self) 的执行应该先于 C.say(self) 。
在 B 类的 say 方法中,使用了 super().say() ,这会按照 MRO 顺序查找下一个类( B 的下一个类是 C ),然后在 C 中调用 say 方法。所以, B.say(self) 的结果是 'FishA' 和 'FishC'。
然后 C.say(self) 被调用,和 B.say(self) 类似,这会导致 C 类中的 say 方法被执行,然后在 C 的父类 A 中查找 say 方法并执行,因此, C.say(self) 的结果是 'FishA' 和 'FishC'。
综上,这段代码的执行顺序和结果是:
- FishA
- FishB
- FishA
- FishC
- FishD
- (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
复制代码
这是由于 super() 调用了 B 的 say 方法,然后 B 类的 say 方法又调用了 super().say() ,按照 MRO 顺序找到了 C 类的 say 方法,而 C 类的 say 方法再次调用了 super().say() 找到了 A 类的 say 方法,之后顺序就是这样产生的。
|
|