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
python2.3中的mro计算顺序为: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* EOne 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.