问题描述
我对Python MRO有问题对于此代码:
I have a problem with the Python MROFor this code:
class F: pass
class G: pass
class H: pass
class E(G,H): pass
class D(E,F): pass
class C(E,G): pass
class B(C,H): pass
class A(D,B,E): pass
print(A.__mro__)
我得到以下输出:
(<class '__main__.A'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.E'>, <class '__main__.G'>, <class '__main__.H'>, <class '__main__.F'>, <class 'object'>)
为什么在<class '__main__.E'>
之前获得<class '__main__.C'>
?
我认为应该是:
-
A
-
D
,B
,E
-
E
,F
|C
,H
|G
,H
A
D
,B
,E
E
,F
|C
,H
|G
,H
以此类推
推荐答案
简而言之,因为 C
依赖于E
,正如您在依赖关系图中看到的那样(O为object
):
In short because C
depends on E
as you can see in the dependency-graph (O is object
):
Python的方法解析顺序(MRO)的约束条件是,如果类 a 是类 b 的依赖项,则它是放在队列中的时间比 b 晚.
Python's method resolution order (MRO) works with the constraint that if a class a is a dependency of a class b, it is placed later in the queue than b.
现在进一步了解该理论:
在Python中,MRO使用以下 linearization 规则:
In Python, the MRO works with the following linearization rule:
L [object
] = object
合并的定义为:
因此,对于您的情况,第一步是:
So for your case, it is, the first step is:
L [] = A
+ merge(L [D
],L [B
],L [E
])
L[A
] = A
+ merge(L[D
],L[B
],L[E
])
让我们首先解决递归调用:
Let us first resolve the recursive calls:
L [D
] = D
+ merge(L [E
],L [F
]);
L [B
] = B
+ merge(L [C
],L [H
]);和
L [E
] = E
+ merge(L [G
],L [H
]).
L[D
] = D
+ merge(L[E
],L[F
]);
L[B
] = B
+ merge(L[C
],L[H
]); and
L[E
] = E
+ merge(L[G
],L[H
]).
更多递归(我们只执行一次H
,而不重做E
):
And more recursion (we only do H
once and do not redo E
):
L [F
] = F
+ merge(L [O
]);
L [C
] = C
+ merge(L [E
],L [G
]);
L [G
] = G
+ merge(L [O
]);和
L [H
] = H
+ merge(L [O
]).
L[F
] = F
+ merge(L[O
]);
L[C
] = C
+ merge(L[E
],L[G
]);
L[G
] = G
+ merge(L[O
]); and
L[H
] = H
+ merge(L[O
]).
由于 L [O
] 是O
和 merge(a)(对于一个对象是 a ),因此,已经获得了H
,G
和F
的序列:
Since L[O
] is O
and merge(a) (for one object is a) we thus have already obtained the sequence for H
, G
and F
:
L [H
] =(H
,O
).
L [G
] =(G
,O
).
L [F
] =(F
,O
).
L[H
] = (H
, O
).
L[G
] = (G
, O
).
L[F
] = (F
, O
).
现在我们可以计算 L [E
] :
Now we can calculate L[E
]:
L [E
] = E
+ merge((G
,O
),(H
,O
)).
L[E
] = E
+ merge( (G
,O
) , (H
,O
) ).
由于O
都位于尾部,因此将其放置在最后:
Since O
is for both in the tail, it is placed last:
L [E
] =(E
,G
,H
,O
).
L[E
] = (E
,G
,H
,O
).
现在我们可以计算 L [C
] :
Now we can calculate L[C
]:
L [C
] = C
+ merge((E
,G
,H
,O
),(G
,O
));
L [C
] =(C
,E
)+ merge((G
,H
,O
),(G
,O
)) ;
L [C
] =(C
,E
,G
)+ merge((H
,O
),(O
));
L [C
] =(C
,E
,G
,H
)+ merge((O
),(O
));
* L [C
] =(C
,E
,G
,H
,O
).
L[C
] = C
+ merge( (E
,G
,H
,O
) , (G
,O
) );
L[C
] = (C
,E
) + merge( (G
,H
,O
) , (G
,O
) );
L[C
] = (C
,E
,G
) + merge( (H
,O
) , (O
) );
L[C
] = (C
,E
,G
,H
) + merge( (O
) , (O
) );
*L[C
] = (C
,E
,G
,H
,O
).
和 L [D
] :
L [D
] = D
+ merge((E
,G
,H
,O
),(F
,O
));
..;
L [D
] =(D
,E
,G
,H
,F
,O
).
L[D
] = D
+ merge( (E
,G
,H
,O
) , (F
,O
) );
..;
L[D
] = (D
,E
,G
,H
,F
,O
).
下一个 L [B
] 可以完全解决:
Next L[B
] can be fully resolved:
L [B
] = B
+ merge((C
,E
,G
,H
,O
),(H
,O
) );
..;
L [B
] =(B
,C
,E
,G
,H
,O
).
L[B
] = B
+ merge( (C
,E
,G
,H
,O
) , (H
,O
) );
..;
L[B
] = (B
,C
,E
,G
,H
,O
).
现在我们终于可以解决:
And now we can finally resolved:
L [] = A
+ merge((D
,E
,G
,H
,F
,O
),(B
, C
,E
,G
,H
,O
),(E
,G
,H
,O
));
L [] =(A
,D
)+ merge((E
,G
,H
,F
,O
),(B
,C
,E
,G
,H
,O
),(E
,G
,H
,O
));
L [] =(A
,D
,B
)+ merge((E
,G
,H
,F
,O
),(C
,E
,G
,H
,O
),(E
,G
,H
,O
));
L [] =(A
,D
,B
,C
)+ merge((E
,G
,H
,F
,O
),(E
,G
,H
,O
),(E
,G
,H
,O
));
L [] =(A
,D
,B
,C
,E
)+ merge((G
,H
,F
,O
),(G
,H
,O
),(G
,H
,O
));
L [] =(A
,D
,B
,C
,E
,G
)+ merge((H
,F
,O
),(H
,O
),(H
,O
));
L [] =(A
,D
,B
,C
,E
,G
,H
)+ merge((F
,O
),(O
),(O
));
L [] =(A
,D
,B
,C
,E
,G
,H
,F
)+ merge((O
),(O
),(O
));
L [] =(A
,D
,B
,C
,E
,G
,H
,F
,O
).
L[A
] = A
+ merge( (D
,E
,G
,H
,F
,O
) , (B
,C
,E
,G
,H
,O
) , (E
,G
,H
,O
) );
L[A
] = (A
,D
) + merge( (E
,G
,H
,F
,O
) , (B
,C
,E
,G
,H
,O
) , (E
,G
,H
,O
) );
L[A
] = (A
,D
,B
) + merge( (E
,G
,H
,F
,O
) , (C
,E
,G
,H
,O
) , (E
,G
,H
,O
) );
L[A
] = (A
,D
,B
,C
) + merge( (E
,G
,H
,F
,O
) , (E
,G
,H
,O
) , (E
,G
,H
,O
) );
L[A
] = (A
,D
,B
,C
,E
) + merge( (G
,H
,F
,O
) , (G
,H
,O
) , (G
,H
,O
) );
L[A
] = (A
,D
,B
,C
,E
,G
) + merge( (H
,F
,O
) , (H
,O
) , (H
,O
) );
L[A
] = (A
,D
,B
,C
,E
,G
,H
) + merge( (F
,O
) , (O
) , (O
) );
L[A
] = (A
,D
,B
,C
,E
,G
,H
,F
) + merge( (O
) , (O
) , (O
) );
L[A
] = (A
,D
,B
,C
,E
,G
,H
,F
,O
).
这是预期的行为.
我制作的效率不高合并功能可用于教育目的,但绝对没有针对生产进行优化:
A not efficient merge function I've made can be used for educational purposes, it is definitely not optimized for production:
def mro_merge(*args):
for i,arg in enumerate(args):
if len(arg) > 0:
head = arg[0]
for argb in args:
if head in argb[1:]:
break
else:
newargs = tuple(argb if len(argb) > 0 and argb[0] != head else argb[1:] for argb in args)
print('mro_merge(%s) = %s + mro_merge(%s)'%(args,head,newargs))
yield head
for x in mro_merge(*newargs):
yield x
break
当您调用它时,它会生成:
And when you call it, it generates:
>>> list(mro_merge(('G','O'),('H','O')))
mro_merge((('G', 'O'), ('H', 'O'))) = G + mro_merge((('O',), ('H', 'O')))
mro_merge((('O',), ('H', 'O'))) = H + mro_merge((('O',), ('O',)))
mro_merge((('O',), ('O',))) = O + mro_merge(((), ()))
['G', 'H', 'O']
>>> list(mro_merge( ('D','E','G','H','F','O') , ('B','C','E','G','H','O') , ('E','G','H','O') ))
mro_merge((('D', 'E', 'G', 'H', 'F', 'O'), ('B', 'C', 'E', 'G', 'H', 'O'), ('E', 'G', 'H', 'O'))) = D + mro_merge((('E', 'G', 'H', 'F', 'O'), ('B', 'C', 'E', 'G', 'H', 'O'), ('E', 'G', 'H', 'O')))
mro_merge((('E', 'G', 'H', 'F', 'O'), ('B', 'C', 'E', 'G', 'H', 'O'), ('E', 'G', 'H', 'O'))) = B + mro_merge((('E', 'G', 'H', 'F', 'O'), ('C', 'E', 'G', 'H', 'O'), ('E', 'G', 'H', 'O')))
mro_merge((('E', 'G', 'H', 'F', 'O'), ('C', 'E', 'G', 'H', 'O'), ('E', 'G', 'H', 'O'))) = C + mro_merge((('E', 'G', 'H', 'F', 'O'), ('E', 'G', 'H', 'O'), ('E', 'G', 'H', 'O')))
mro_merge((('E', 'G', 'H', 'F', 'O'), ('E', 'G', 'H', 'O'), ('E', 'G', 'H', 'O'))) = E + mro_merge((('G', 'H', 'F', 'O'), ('G', 'H', 'O'), ('G', 'H', 'O')))
mro_merge((('G', 'H', 'F', 'O'), ('G', 'H', 'O'), ('G', 'H', 'O'))) = G + mro_merge((('H', 'F', 'O'), ('H', 'O'), ('H', 'O')))
mro_merge((('H', 'F', 'O'), ('H', 'O'), ('H', 'O'))) = H + mro_merge((('F', 'O'), ('O',), ('O',)))
mro_merge((('F', 'O'), ('O',), ('O',))) = F + mro_merge((('O',), ('O',), ('O',)))
mro_merge((('O',), ('O',), ('O',))) = O + mro_merge(((), (), ()))
['D', 'B', 'C', 'E', 'G', 'H', 'F', 'O']
这篇关于为什么在MRO中以这种方式订购课程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!