python mro computing

来源:互联网 发布:网络日语学校 编辑:程序博客网 时间:2024/05/17 00:17
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 localprecedence ordering and monotonicity. In this section, I will showthat both the MRO for classic classes and the MRO for new style classesin Python 2.2 are bad.

It is easier to start with the local precedence ordering. Consider thefollowing 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: thereforewe would expect the attribute G.remember2buy to be inherited byF.rembermer2buy and not by E.remember2buy: nevertheless Python 2.2gives

>>> G.remember2buy
'eggs'

This is a breaking of local precedence ordering since the order in thelocal precedence list, i.e. the list of the parents of G, is notpreserved 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.2linearization is that F is less specialized than E, since F is thesuperclass of E; nevertheless the breaking of local precedence orderingis quite non-intuitive and error prone. This is particularly true sinceit 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 ispreserved.


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


参考文档:
http://www.python.org/download/releases/2.3/mro/
原创粉丝点击