python mro computing

本文深入探讨了Python中MRO(方法解析顺序)的概念及其计算规则,对比了Python 2.2与2.3版本中MRO实现的不同,并通过实例展示了如何确保本地顺序和单调性原则得以遵循。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. mro , metod resolutin order,用于决定方法的解析顺序,即确定调用那一个类中的方法
2. 解析时要遵循的标准:
        a. 本地顺序:在一个类C的直接父类解析顺序要与写在c的声明中一致,例如C(A,B),如果A,B都有一个同名的函数,那么在调用C.xxx时应该调用A的这个方法,而非B的方法
        b. 单调性,即如果在c的解析顺序里,A排在B的前面,那么在c的所有子类里,这个顺序也必须被满足。

在经典类里,python使用深度优先,然后从左向右的顺序,这样会导致本地顺序不能被满足,例如:

Bad Method Resolution Orders

A MRO is bad when it breaks such fundamental properties as local precedence ordering and monotonicity. In this section, I will show that both the MRO for classic classes and the MRO for new style classes in Python 2.2 are bad.

It is easier to start with the local precedence ordering. Consider the following example:

>>> F=type('Food',(),{'remember2buy':'spam'})
>>> E=type('Eggs',(F,),{'remember2buy':'eggs'})
>>> G=type('GoodFood',(F,E),{}) # under Python 2.3 this is an error!

with inheritance diagram

             O
|
(buy spam) F
| /
| E (buy eggs)
| /
G

(buy eggs or spam ?)

We see that class G inherits from F and E, with F before E: therefore we would expect the attribute G.remember2buy to be inherited by F.rembermer2buy and not by E.remember2buy: nevertheless Python 2.2 gives

>>> G.remember2buy
'eggs'

This is a breaking of local precedence ordering since the order in the local precedence list, i.e. the list of the parents of G, is not preserved in the Python 2.2 linearization of G:

L[G,P22]= G E F object   # F *follows* E

One could argue that the reason why F follows E in the Python 2.2 linearization is that F is less specialized than E, since F is the superclass of E; nevertheless the breaking of local precedence ordering is quite non-intuitive and error prone. This is particularly true since it is a different from old style classes:

>>> class F: remember2buy='spam'
>>> class E(F): remember2buy='eggs'
>>> class G(F,E): pass
>>> G.remember2buy

'spam'

In this case the MRO is GFEF and the local precedence ordering is preserved.


 python2.3中的mro计算顺序为:
take the head of the first list, i.e L[B1][0]; if this head is not in the tail of any of the other lists, then add it to the linearization of C and remove it from the lists in the merge, otherwise look at the head of the next list and take it, if it is a good head. Then repeat the operation until all the class are removed or it is impossible to find good heads. In this case, it is impossible to construct the merge, Python 2.3 will refuse to create the class C and will raise an exception.


参考文档:
http://www.python.org/download/releases/2.3/mro/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值