本文介绍了为什么在MRO中以这种方式订购课程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对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'>?

我认为应该是:

  1. A
  2. DBE
  3. EF | CH | GH
  1. A
  2. D,B,E
  3. 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 ),因此,已经获得了HGF的序列:

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] =(HO).
L [G] =(GO).
L [F] =(FO).

L[H] = (H, O).
L[G] = (G, O).
L[F] = (F, O).

现在我们可以计算 L [E] :

Now we can calculate L[E]:

L [E] = E + merge((GO),(HO)).

L[E] = E + merge( (G,O) , (H,O) ).

由于O都位于尾部,因此将其放置在最后:

Since O is for both in the tail, it is placed last:

L [E] =(EGHO).

L[E] = (E,G,H,O).

现在我们可以计算 L [C] :

Now we can calculate L[C]:

L [C] = C + merge((EGHO),(GO));
L [C] =(CE)+ merge((GHO),(GO)) ;
L [C] =(CEG)+ merge((HO),(O));
L [C] =(CEGH)+ merge((O),(O));
* L [C] =(CEGHO).

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((EGHO),(FO));
..;
L [D] =(DEGHFO).

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((CEGHO),(HO) );
..;
L [B] =(BCEGHO).

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((DEGHFO),(BCEGHO),(EGHO));
L [] =(AD)+ merge((EGHFO),(BCEGHO),(EGHO));
L [] =(ADB)+ merge((EGHFO),(CEGHO),(EGHO));
L [] =(ADBC)+ merge((EGHFO ),(EGHO),(EGHO));
L [] =(ADBCE)+ merge((GHFO ),(GHO),(GHO));
L [] =(ADBCEG)+ merge((HFO ),(HO),(HO));
L [] =(ADBCEGH)+ merge((FO ),(O),(O));
L [] =(ADBCEGHF)+ merge((O ),(O),(O));
L [] =(ADBCEGHFO).

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中以这种方式订购课程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-27 23:45
查看更多