zoukankan      html  css  js  c++  java
  • python新式类继承------C3算法

    一、引入

    mro即method resolution order,主要用于在多继承时判断调的属性的路径(来自于哪个类)。之前查看了很多资料,说mro是基于深度优先搜索算法的。但不完全正确在Python2.3之前是基于此算法,但从Python2.3起应用了新算法:C3算法。

    二、为什么采用C3算法

    C3算法最早被提出是用于Lisp的,应用在Python中是为了解决原来基于深度优先搜索算法不满足本地优先级,和单调性的问题。
    本地优先级:指声明时父类的顺序,比如C(A,B),如果访问C类对象属性时,应该根据声明顺序,优先查找A类,然后再查找B类。
    单调性:如果在C的解析顺序中,A排在B的前面,那么在C的所有子类里,也必须满足这个顺序。

    三、C3算法的实现

    1.多继承UML图:

                                               

    2.python-C3算法解析:

    判断mro要先确定一个线性序列,然后查找路径由由序列中类的顺序决定。所以C3算法就是生成一个线性序列。
    如果继承至一个基类:
    class B(A)
    这时B的mro序列为[B,A]
     
    如果继承至多个基类
    class B(A1,A2,A3 ...)
    这时B的mro序列 mro(B) = [B] + merge(mro(A1), mro(A2), mro(A3) ..., [A1,A2,A3])
     

    C3算法的本质就是Merge,不断地把mro()函数返回的序列进行Merge,规则如下:

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

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

    merge: ① 如果列表空则结束,非空 读merge中第一个列表的表头,
                   ② 查看该表头是否在 merge中所有列表的表尾中。
                   ②-->③ 不在,则 放入 最终的L中,并从merge中的所有列表中删除,然后 回到①中
                   ②-->④ 在,查看 当前列表是否是merge中的最后一个列表
                   ④-->⑤ 不是 ,跳过当前列表,读merge中下一个列表的表头,然后 回到 ②中
                   ④-->⑥ 是,异常。类定义失败。 
    表头: 列表的第一个元素 (列表:ABC,那么表头就是A,B和C就是表尾)
    表尾: 列表中表头以外的元素集合(可以为空) 
    merge 简单的说即寻找合法表头(也就是不在表尾中的表头),如果所有表中都未找到合法表头则异常。

    例如:

    L(A(B,C)) = A + merge(L(B),L(C),BC)
              = A + merge(BDEO,CEFO,BC)#B是合法表头
              = A + B + merge(DEO,CEFO,C)#D是合法表头
              = A + B + D + merge(EO,CEFO,C)#E不是合法表头,跳到下一个列表CEFO,此时C是合法表头
              = A + B + D + C + merge(EO,EFO)#由于第三个列表中的C被删除,为空,所以不存在第三个表,只剩下两个表;此时E是合法表头
              = A + B + D + C + E + merge(O,FO)#O不是合法表头,跳到下一个列表FO,F是合法表头,
              = A + B + D + C + E + F + merge(O,O)#O是合法表头
              = A + B + D + C + E + F + O
              = [A,B,D,C,E,F,O]

  • 相关阅读:
    pycharm 对mysql的可视化操作
    pycharm连接linux创建django工程
    linux上安装pycharm
    pycharm激活码
    Windows下安装pip
    migrate设置
    python相对目录的基本用法(一)
    pycharm设置连接github
    在shell终端操作oracle数据库的常用命令
    在windows中把一个文件夹打成war包
  • 原文地址:https://www.cnblogs.com/fengchong/p/10079698.html
Copyright © 2011-2022 走看看