C3算法之我见

时间:2022-11-30 20:28:30

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规则:

  1. 如果第一个序列的第一个元素,是后续序列的第一个元素,或者不再后续序列中再次出现,则将这个元素合并到最终的方法解析顺序序列中,并从当前操作的全部序列中删除。

  2. 如果不符合,则跳过此元素,查找下一个列表的第一个元素,重复1的判断规则

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

"""