zoukankan      html  css  js  c++  java
  • python3中的新式类mro查看和C3算法原理

    两个公式
    L(object) = [object]
    L(子类(父类1, 父类2)) = [子类] + merge(L(父类1), L(父类2) , [父类1, 父类2])
    注意
    + 代表合并列表
    merge算法
    1. 第一个列表的第一个元素
    是后续列表的第一个元素
    或者
    后续列表中没有再次出现
    则将这个元素合并到最终的解析列表中
    并从当前操作的所有列表中删除
    2. 如果不符合,则跳过此元素,查找下一个列表的第一个元素,重复1的判断规则
    3. 如果最终无法把所有元素归并到解析列表, 则报错

    # 菱形继承
    class D(object):
        pass
    # L(D(objecj)) = [D] + mearge(L(object), [object])
    #              = [D] + mearge([object], [object])
    #              = [D] + mearge([], [])
    #              = [D, object]
    
    
    class B(D):
        pass
    # L(B(D)) = [B] + mearge(L(D), [D])
    #         = [B] + mearge([D, object], [D])
    #         = [B, D] + mearge([object], [])
    #         = [B, D, object] + mearge([], [])
    #         = [B, D, object]
    
    
    class C(D):
        pass
    # L(C(D)) = [C] + mearge(L(D), [D])
    #         = [C] + mearge([D, object], [D])
    #         = [C, D] + mearge([object], [])
    #         = [C, D, object] + mearge([], [])
    #         = [C, D, object]
    
    
    class A(B, C):
        pass
    # L(A) = [A] + mearge(L(B), L(C), [B, C])
    #      = [A] + mearge([B, D, object],[C, D, object], [B, C])
    #      = [A, B] + mearge([D, object],[C, D, object], [C])
    #      = [A, B, C] + mearge([D, object],[D, object])
    #      = [A, B, C, D] + mearge([object],[object])
    #      = [A, B, C, D, object] + mearge([],[])
    #      = [A, B, C, D, object]
    
    print(A.mro())
    print(A.__mro__)
    import inspect
    print(inspect.getmro(A))
    表头 表尾
    表头 列表的第一个元素
    表尾 列表中表头以外的元素集合(可以为空)
    [A,B,D,C] A表头 BDC 表尾
    merge( [E,O], [C,E,F,O], [C] )
    取出第一个列表的表头 E 所有列表的表尾 O E F O ''
    如果E 在所有的表尾中,那么就跳过这个列表
    merge( [E,O], [C,E,F,O], [C] )
    第二个列表表头: C O EFO '' 将C 单独提出
    [c] + merge([E,O], [E,F,O])
    mro(C) = mro(C(B,A)) = [C] + merge(mro(B),mro(A),[B,A])
    mro(A) = mro(A(B,C))

    # 新式类:
    # class A:
    #     pass
    #
    # class B:
    #     pass
    #
    # class C(B,A):
    #     pass
    # #mro(Child(Base1,Base2)) = [ Child ] + merge( mro(Base1), mro(Base2), [ Base1, Base2] )
    # # mro(C) = mro(C(B,A)) = [C] + merge(mro(B),mro(A),[B,A])
    #

    class O:
        def func(self):
            print('in O')
    class D(O): pass # def func(self): # print('in D') class E(O): pass # def func(self): # print('in E') class F(O): def func(self): print('in F') class B(D, E): pass # def func(self): # print('in B') # mro(B) = mro(B(D,E)) # mro(B(D,E)) = [B] + merge(mro(D),mro(E),[D,E]) # mro(B(D,E)) = [B] + merge([D,O],[E,O],[D,E]) # mro(B(D,E)) = [B,D] + merge([O],[E,O],[E]) # mro(B(D,E)) = [B,D,E] + merge([O],[O]) # mro(B(D,E)) = [B,D,E,O] class C(E, F): pass # def func(self): # print('in C') # mro(C) = mro(C(E,F)) # mro(C(E,F)) = [C] + merge([E,O],[F,O],[E,F]) # mro(C(E,F)) = [C,E] + merge([O],[F,O],[F]) # mro(C(E,F)) = [C,E,F] + merge([O],[O]) # mro(C(E,F)) = [C,E,F,O] class A(B, C): def func(self): super().func() print('in A') # mro(A(B,C)) = [A] + merge(mro(B),mro(C),[B,C]) # mro(A(B,C)) = [A] + merge([B,D,E,O],[C,E,F,O],[B,C]) # mro(A(B,C)) = [A,B] + merge([D,E,O],[C,E,F,O],[C]) # mro(A(B,C)) = [A,B,D] + merge([E,O],[C,E,F,O],[C]) # mro(A(B,C)) = [A,B,D,C] + merge([E,O],[E,F,O]) # mro(A(B,C)) = [A,B,D,C,E] + merge([O],[F,O]) # mro(A(B,C)) = [A,B,D,C,E,F] + merge([O],[O]) # mro(A(B,C)) = [A,B,D,C,E,F,O] obj = A() obj.func() # mro(A(B,C)) = [A,B,D,C,E,F,O] print(A.__mro__) # super 遵循mro 顺序

    练习

    class A:
        pass
    
    class B(A):
        pass
    
    class C(A):
        pass
    
    class D(A):
        pass
    
    class E(B,C):
        pass
    
    class F(C,D):
        pass
    
    class G(D):
        pass
    
    class H(E,F):
        pass
    
    class I(F,G):
        pass
    
    class K(H,I):
        pass
    
    # print(K.mro())
    # print(E.mro())
    # print(F.mro())
    # print(G.mro())
    # print(I.mro())
    # print(H.mro())
    
    
    '''
    mro(K(H, I)) = [K] + merge(mro(H), mro(I), [H, I])
    mro(K(H, I)) = [K] + merge(mro[H, E, B, F, C, D, A], [I, F, C, G, D, A], [H, I])
    mro(K(H, I)) = [K, H] + merge(mro[E, B, F, C, D, A], [I, F, C, G, D, A], [I])
    mro(K(H, I)) = [K, H, E, B, I] + merge(mro[F, C, D, A], [F, C, G, D, A])
    mro(K(H, I)) = [K, H, E, B, I, F, ] + merge(mro[C, D, A], [C, G, D, A])
    mro(K(H, I)) = [K, H, E, B, I, F, C, ] + merge(mro[D, A], [G, D, A])
    mro(K(H, I)) = [K, H, E, B, I, F, C, G] + merge(mro[D, A], [D, A])
    mro(K(H, I)) = [K, H, E, B, I, F, C, G, D, A]
    
    
    
    mro(H)
    mro(H(E, F)) = [H] + merge(mro(E), mro(F), [E, F])
    mro(H(E, F)) = [H] + merge([E, B, C, A], [F, C, D, A], [E, F])
    mro(H(E, F)) = [H, E] + merge([B, C, A], [F, C, D, A], [F])
    mro(H(E, F)) = [H, E, B] + merge([C, A], [F, C, D, A], [F])
    mro(H(E, F)) = [H, E, B, F] + merge([C, A], [C, D, A])
    mro(H(E, F)) = [H, E, B, F, C] + merge([A], [D, A])
    mro(H(E, F)) = [H, E, B, F, C, D, A]
    
    
    
    mro(I)
    mro(I(F, G)) = [I] + merge(mro(F), mro(G), [F, G])
    mro(I(F, G)) = [I] + merge([F, C, D, A], [G, D, A], [F, G])
    mro(I(F, G)) = [I, F] + merge([C, D, A], [G, D, A], [G])
    mro(I(F, G)) = [I, F, C] + merge([D, A], [G, D, A], [G])
    mro(I(F, G)) = [I, F, C] + merge([D, A], [D, A])
    mro(I(F, G)) = [I, F, C, G, D] + merge([A], [A])
    mro(I(F, G)) = [I, F, C, G, D, A]
    
    mro(E)
    mro(E(B, C)) = [E] + merge(mro(B), mro(C), [B, C])
    mro(E(B, C)) = [E] + merge([B, A], [C, A], [B, C])
    mro(E(B, C)) = [E, B] + merge([A], [C, A], [C])
    mro(E(B, C)) = [E, B, C] + merge([A], [A])
    mro(E(B, C)) = [E, B, C, A]
    
    mro(F)
    mro(F(C, D)) = [F] + merge(mro(C), mro(D), [C, D])
    mro(F(C, D)) = [F] + merge([C, A], [D, A], [C, D])
    mro(F(C, D)) = [F, C] + merge([A], [D, A], [D])
    mro(F(C, D)) = [F, C, D] + merge([A], [A])
    mro(F(C, D)) = [F, C, D, A]
    
    mro(G)
    mro(G(D)) = [G, D, A]
    '''
  • 相关阅读:
    Mac使用nginx+rtmp服务器
    iOS开发必不可少的76个工具
    AVPlayer缓存实现
    视频直播分析
    github部分有意思的库记录
    iOS四种多线程(swift和oc)
    Java的static关键字浅析
    JavaScript获取屏幕参数
    JavaScript中XMLHttpRequest实现跨域访问
    【CenchaTouch 学习笔记】Controller
  • 原文地址:https://www.cnblogs.com/chen55555/p/10274310.html
Copyright © 2011-2022 走看看