• C3算法之我见


    C3算法说到底就是merge算法,看了一些帖子,总结说得莫名其妙,大家也是抄来抄去,我试着用自己的话来把这个东西怎么操作的说清楚。当然了我也要抄一些别人的,但是我会 尽量把我认为别人没有讲清楚的那一部分东西说清楚。还是得从一个例子说起,毕竟一来就说一大段理论我认为是在耍流氓。

    class A:
    pass
    class B(A):
    pass
    class C(A):
    pass
    class D(B, C):
    pass
    class E(C, A):
    pass
    class F(D, E):
    pass
    class G(E):
    pass
    class H(G, F):
    pass

    首先. 我们要确定从H开始找. 也就是说. 创建的是H的对象.
    如果从H找. 那找到H+H的父类的C3, 我们设C3算法是L(x) , 即给出x类. 找到x的MRO
    L(H) = H + L(G) + L(F)
    继续从代码中找G和F的⽗父类往里面带
    L(G) = G + L(E)
    L(F) = F + L(D)+ L(E)
    继续找E 和 D
    L(E) = E + L(C) + L(A)
    L(D) = D + L(B) + L(C)
    继续找B和C
    L(B) = B + L(A)
    L(C) = C + L(A)
    最后就剩下一个A了. 也就不用再找了.
    接下来. 把L(A) 往里带. 再推回去. 但要记住. 这里的 + 表示的是merge.

    merge的原则是⽤每个元组的头⼀项和后⾯元组的除头⼀项外的其他元素进⾏比较, 看是否存在。如果存在,就从下⼀个元组的头⼀项继续找,如果找不到,就拿出来。作为merge的结果的⼀项,以此类推,直到元组之间的元素都相同,也就不⽤再找了。

    L(B) =(B,) + (A,) -> (B, A) 

    L(C) =(C,) + (A,) -> (C, A)
    继续带.
    L(E) = (E,) + (C, A) + (A) -> E, C, A
    L(D) = (D,) + (B, A) + (C, A) -> D, B,C, A

    下面我们来看个例子:

    拿上面这个L(D)举个例子,D不在后面出现,拿出来,B也不在后面,也拿出来。在B拿出来之后,merge里面里面的情况:D,B

    此时L(D)=(A,)+(C,A)。OK,我们现在继续进行merge,现在tuple里面的头元素A出现在后面tuple的非头元素位置,因此要跳过A,然后,后面的(C,A)都满足条件

    因此上面merge的结果是:D,B,C,A
    继续带.
    L(G) = (G,) + (E, C, A) -> G, E, C, A
    L(F) = (F,) + (D, B, A) + (E, C, A) -> F, D, B, E, C, A
    加油, 最后了
    L(H) = (H, ) + (G, E, C, A) + ( F, D, B, E, C, A) -> H, G, F, D, B, E, C, A

    """
    [<class '__main__.H'>,<class '__main__.G'>,
    <class '__main__.F'>, <class '__main__.D'>,
    <class '__main__.B'>, <class '__main__.E'>,
    <class '__main__.C'>, <class '__main__.A'>,
    <class 'object'>]

    """
  • 相关阅读:
    C#中的Dictionary字典类介绍
    SQL server 2008r2 file is corrupt
    web service接口 wsdl和asmx有什么区别
    ascx
    C++: C++函数声明的时候后面加const
    C++三种野指针及应对/内存泄露
    C++构造和析构的顺序
    atan2()如何转换为角度
    C++11左值引用和右值引用
    C++ STL详解
  • 原文地址:https://www.cnblogs.com/d9e84208/p/10602718.html
Copyright © 2020-2023  润新知