当前位置:  开发笔记 > 编程语言 > 正文

为什么在MRO中以这种方式订购课程?

如何解决《为什么在MRO中以这种方式订购课程?》经验,为你挑选了1个好方法。

我有Python MRO的问题对于这段代码:

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__)

我得到这个输出:

(, , , , , , , , )

我为什么要来之前

我以为会是:

    A

    D,B,E

    E,F| C,H| G,H

等等



1> Willem Van O..:

总之,因为C取决于E你可以在依赖-图(O是见object):

在此输入图像描述

Python的方法解析顺序(MRO)使用约束,即如果类a是类b的依赖关系,则它放在队列中的后面而不是b.

现在更多的理论:

在Python中,MRO使用以下线性化规则:

L [ C(B1 ... Bn)] = C + merge(L [ B1] ... L [ Bn],B1... Bn) ; 和

L [ object] =object

(资源)

合并被定义为:

取第一个清单的头部,即L [ B1] [0]; 如果这个头不在任何其他列表的尾部,那么将它添加到C的线性化并将其从合并中的列表中删除,否则查看下一个列表的头部并将其取出,如果它是好头.然后重复操作,直到所有课程都被删除或者找不到好头.在这种情况下,不可能构造合并,Python 2.3将拒绝创建类C并将引发异常.

(资源)

所以对于你的情况来说,第一步是:

L [ A] = A+合并(L [ D],L [ B],L [ E])

我们先解决递归调用:

L [ D] = D+ merge(L [ E],L [ F]) ;
L [ B] = B+ merge(L [ C],L [ H]) ; 和
L [ E] = E+合并(L [ G],L [ H]).

更多的递归(我们只执行H一次而不重做E):

L [ F] = F+ merge(L [ O]) ;
L [ C] = C+ merge(L [ E],L [ G]) ;
L [ G] = G+ merge(L [ O]) ; 和
L [ H] = H+合并(L [ O]).

由于L [ O]Omerge(a)(对于一个对象是a),因此我们已经获得了序列H,G并且F:

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

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

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

既然O是尾部的两个,它放在最后:

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

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

L [ C] = C+合并(( ,E,G,H),(O ,))GO ;
L [ C] =( C,E)+合并(( ,G,H),(O ,))GO ;
L [ C] =( ,,C )+合并(( ,),( ))EGHOO ;
L [ C] =( ,C,,E )+合并(( ),())GHOO ;
*L [ C] =( ,C,E,G,).HO

L [ D]:

L [ D] = D+合并(( ,E,G,H),(O ,))FO ;
..;
L [ D] =( ,D,E,G,H,F)O.

下一个L [ B]可以完全解决:

L [ B] = B+合并(( ,C,E,G,H),(O ,))HO ;
..;
L [ B] =( ,B,C,E,G,H)O.

现在我们终于可以解决了:

L [ A] = A+合并(( ,D,E,G,H,F),(O, , ,B,C,),(E , ,, ))GHOEGHO ;
L [ A] =( A,D)+合并(( ,E,G,H,F),(O, , ,B,C,),(E , ,, ))GHOEGHO ;
L [ A] =( ,,A )+合并(( ,,,,),(, , ,,),( , ,, ))DBEGHFOCEGHOEGHO ;
L [ A] =( ,A,,D )+合并(( ,,,,),(, , ,),( , ,, ))BCEGHFOEGHOEGHO ;
L [ A] =( ,A,D,,B )+合并(( ,,,),(, , ),( , ,))CEGHFOGHOGHO ;
L [ A] =( ,A,D,B,,C )+合并(( ,,),(, ),( ,))EGHFOHOHO ;
L [ A] =( ,A,D,B,C,,E )+合并(( ,),(),( ))GHFOOO ;
L [ A] =( ,A,D,B,C,E,,G )+合并(( ),(),( ))HFOOO ;
L [ A] =( ,A,D,B,C,E,G,H,F)O.

这是预期的行为.

我所做的一个非常有效的合并功能可以用于教育目的,它绝对没有针对生产进行优化:

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

当你调用它时,它会生成:

>>> 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']

推荐阅读
oDavid_仔o_880
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有