(进)Python MRO解析顺序(Method Resolution Order)

C3算法

Python 至少用过三种不同的 MRO 算法:经典类所用的算法,Python 2.2 中的新式类所用算法,以及 Python 2.3 中的新式类所用的算法(也称 C3算法),而在 Python 3 中,只留下了最后一种算法。
C3是如何构建一个类的线性化(优先级)。这个列表可用于属性查找。

MRO

MRO的变化是用于解决创建公共基本类型(object)所引入的问题。在C3线性化方法之前,如果一个类有两个祖先(图3-1),那么对于不使用多重继承模型的简单情况来说,方法解析顺序的计算和跟踪都非常简单。

示例图

在这里插入图片描述

>>> class Base1:
...     pass
... 
>>> class Base2:
...     def method(self):
...         print('Base2')
...         
>>> 
>>> class Myclass(Base1, Base2):
...     pass
... 
>>> Myclass.__mro__
(<class 'Myclass'>, <class 'Base1'>, <class 'Base2'>, <class 'object'>)
>>> Myclass().method()
Base2

# 当调用MyClass().method()时,解释器会首先在MyClass中查找这一方法,然后在Base1中查找,最终在Base2中找到
# 经典类中的 MRO 算法非常简单:深度优先,从左至右,返回找到的第一个结果
Base1和Base2基类引入某个类

双祖先类再引入某个CommonBase类(Base1和Base2都从其继承,图3-2),将变得更加复杂。其结果,根据“从左到右、深度优先”规则的简单解析顺序,在查找Base2类之前就通过Base1类回到顶部。这一算法会导致反直觉的结果。在某些情况下,执行的方法可能并不是在继承树中最为接近的那个方法。

Python 2中继承
>>> class CommonBase:
...     def method(self):
...         print('CommonBase')
...         
>>> 
>>> class Base1(CommonBase):
...     pass
... 
>>> 
>>> class Base2(CommonBase):
...     def method(self):
...         print('Base2')
...         
>>> 
>>> class Myclass(Base1, Base2):
...     pass
... 
>>> 
>>> Myclass().method()
CommonBase

# Base2.method()没有被调用,虽然在类层次结构中 Base2 比 CommonBase 要更近一些。
# 这样的继承情景是极其少见的,因此更多的是一个理论问题而不是实践问题。

Python 3中继承
>>> class CommonBase:
...     def method(self):
...         print('CommonBase')
...         
>>> 
>>> class Base1(CommonBase):
...     pass
... 
>>> 
>>> class Base2(CommonBase):
...     def method(self):
...         print('Base2')
...         
>>> 
>>> class Myclass(Base1, Base2):
...     pass
... 
>>> 
>>> Myclass().method()
Base2
# 现在Python3中所有类具有相同的共同祖先。由于使用现有的MRO使其正常工作要花费太多的精力,所以提供一个新的MRO是更为简单、快捷的解决方案。

# 这种用法表明,C3序列化会挑选最接近的祖先的方法。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

魔幻云

告诉自己是时候输出知识啦!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值