Movatterモバイル変換


[0]ホーム

URL:


[Python-Dev] perplexed by mro

Samuele Pedronipedronis@bluewin.ch
Tue, 1 Oct 2002 21:59:00 +0200


I'm trying to wrap my head around the mro computation in 2.2.First issue: PEP 253 and the descrintro document describe an algorithm,typeobject.c implements a rather different one. Descrintro mentions that.The algorithm described by descrintro, PEP253:"Using the classic lookup rule, construct the list of classes that would besearched, including duplicates. Now for each class that occurs in the listmultiple times, remove all occurrences except for the last."which, if I understand correctly, means : do a left-right dfs of the classhierarchy and then discard all but the last occurence of each class.Now descrintro says that the result of this and the real algorithm intypeobject are the same, unless"two given base classes occur in a different order in the inheritance list oftwo different derived classes, and those derived classes are both inherited byyet another class"But here is an example where the criterium does not apply but still thealgorithms' results diverge:>>> cpl.ex5(globals())class a(object): passclass b(object): passclass c(object): passclass x(a): passclass y(a): passclass z(x,b,y,c): pass>>> cpl.names(z.__mro__) # just the class names, real 2.2 mro algo['z', 'x', 'y', 'a', 'b', 'c', 'object']>>> cpl.names(cpl.keeplast(cpl.lrdfs(z))) # descrintro simple algo['z', 'x', 'b', 'y', 'a', 'c', 'object']I was not able to find a new rule. My intuition is that when the result of thereal mro has something to do with the dfs, it is sure from the beginning of itnot the end, so the relation of the two algos is unclear.In general I have an hard time trying to predict the result of the real mroalgo.Does it a have a list of constraints it enforces/preserves, of the qualities ithas?I have tried to compare it to the algorithms used by Dylan and CLOS and others,described in this paperhttp://www.webcom.com/haahr/dylan/linearization-oopsla96.htmlthey are described in terms such as quality criteria and constraints theypreserve.Let's consider this example:>>> cpl.ex9(globals())class a(object): passclass b(object): passclass c(object): passclass d(object): passclass e(object): passclass k1(a,b,c): passclass k2(d,b,e): passclass k3(d,a): passclass z(k1,k2,k3): pass>>> cpl.names(z.__mro__)['z', 'k1', 'k3', 'a', 'k2', 'd', 'b', 'c', 'e', 'object']the thing that leaves me most perplexed is that k3 appears before k2. All otheralgortihms I know would put k2 before k3.E.g. C3 (see paper) ...>>> cpl.names(cpl.c3_cpl(z))['z', 'k1', 'k2', 'k3', 'd', 'a', 'b', 'c', 'e', 'object']or the descrintro simple algo:>>> cpl.names(cpl.keeplast(cpl.lrdfs(z)))['z', 'k1', 'c', 'k2', 'b', 'e', 'k3', 'd', 'a', 'object']This means that it does not preserve the local precedence lists (i.e. theinheritance list), it is not monotonic* because otherwise it would put d beforea, it seems to preserve "some" aspects of the dfs traversal a,d vs d,a butstill it puts k3 before k2.The other hypothesis, is that in this case, the algorithm should fail, becauseit cannot merge the result of mro(k1) merged with mro(k2) with mro(k3), becausethe latter is inconsistent with what obtained so far?>>> l=cpl.names(k1.__mro__)>>> l['k1', 'a', 'b', 'c', 'object']>>> r=cpl.names(k2.__mro__)>>> cpl.conservative_merge(l,r) ...>>> l['k1', 'a', 'k2', 'd', 'b', 'c', 'e', 'object']vs.>>> cpl.names(k3.__mro__)['k3', 'd', 'a', 'object']a<d is incosistent with d<aBut then this inconsistency rule is different/subtler than the one sketched indescrintro.So can someone (Guido?) summarize the qualities of this rule? is there a paperthat describes it? or should I buy the book?regards.* the mro of a subclass is an extension without re-ordering of the mros of thesuperclasses.


[8]ページ先頭

©2009-2025 Movatter.jp