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]

  • 相关阅读:
    联网大数据运用的九大领域
    写给喜欢数据分析的初学者
    里阳起诉国外企业,中小企业海外维权绝不手软
    自己动手写CPU之第七阶段(2)——简单算术操作指令实现过程
    我为创业狂——成都传智播客学员故事
    Python学习笔记18:标准库之多进程(multiprocessing包)
    Android开发:LocationManager获取经纬度及定位过程(附demo)
    [nio]dawn的基本概念
    iOS_39_触摸解锁
    POJ 2965:The Pilots Brothers' refrigerator
  • 原文地址:https://www.cnblogs.com/fengchong/p/10079698.html
Copyright © 2011-2022 走看看