• python多继承下的查找顺序-MRO原则演变与C3算法


    在python历史版本中的演变史

    python2.2之前:

    MRO原则:

      只有经典类,遵循深度优先(从左到右)原则,

      存在的问题:在有重叠的多继承中,违背重写可用原则

      解决办法是再设计类的时候不要设计这样有问题的类

    python2.2版本:

    MRO原则:

      经典类:遵循深度优先(从左到右)原则

      引入新式类:在深度优先(从左到右)的算法基础之上, 优化了一部分,如果产生重复元素, 会保留最后一个,并且, 更尊重基类出现的先后顺序

        新式类存在的问题:无法检测出有问题的继承,

                 有可能还会违背局部优先的原则

                例如:

                  

     

    python2.3-2.7版本:

    MRO原则:

      经典类:遵循深度优先(从左到右)原则

      新式类:C3算法

    python3.x之后:MRO原则:

      只有新式类:C3算法

    C3算法详解:

    公式:

      L(object) = [ object ]

      L(子类(父类1,父类2)) =  [ 子类 ] + merge(L(父类1) + L(父类2) + [父类1,父类2])

      注意:+ 代表合并列表

      mergel算法:

        1、第一个列表中的第一个元素如果是后面列表中的首个元素或者在后面列表中不存在,则将这个元素合并到merge函数前面的最终列表中,并删除这个元素

        2、如果第一个列表第一个元素不成立,则查看第二个列表首个元素,执行第1步操作

        3、如果最终无法把所有元素都归到最终的解析列表中,则报错,说明是错误的继承关系

    案列代码:

     class D(object):
    #     pass
    
    # L(D(object)) = [D] + merge(L(object), [object])
    #              = [D] + merge([object], [object])
    #              = [D, object] + merge([], [])
    #              = [D, object]
    
    # class B(D):
    #     pass
    
    # L(B(D)) = [B] + merge(L(D), [D])
    #         = [B] + merge([D, object], [D])
    #         = [B, D] + merge([object], [])
    #         = [B, D, object] + merge([], [])
    #         = [B, D, object]
    
    
    # class C(D):
    #     pass
    # L(C(D)) = [C, D, object]
    
    # class A(B, C):
    #     pass
    # L(A) = [A] + merge(L(B), L(C), [B, C])
    #      = [A] + merge([B, D, object], [C, D, object], [B, C])
    #      = [A, B] + merge([D, object], [C, D, object], [C])
    #      = [A, B, C] + merge([D, object], [D, object])
    #      = [A, B, C, D] + merge([object], [object])
    #      = [A, B, C, D, object] + merge([], [])
    #      = [A, B, C, D, object]

    查看继承顺序的方法

    1、import inspect

      print(inspect.getmro(类))

    2、类.mro()

      类.__mro__()

        

      

  • 相关阅读:
    【转】汽车CAN总线
    【转】I2C总线协议
    【转】SPI总线协议
    【转】结构struct 联合Union和枚举Enum的细节讨论
    复合类型变量其首地址的几种表示方式
    【转】四款经典3.7v锂电池充电电路图详解
    【转】crc16几种标准校验算法及c语言代码
    【转】 CRC循环冗余校验码
    对STM32库函数中 assert 函数的认知
    【转】用宏定义代替printf函数
  • 原文地址:https://www.cnblogs.com/jayxuan/p/11073742.html
Copyright © 2020-2023  润新知