C3算法

一、知识点补充:

拓扑排序:在图论中,拓扑排序(Topological Sorting) 是一个 有向无环图(DAG,Directed Acyclic Graph) 的所有顶点的线性序列。且该序列必须满足下面两个条件:

  1. 每个顶点出现且只出现一次

  2. 若存在一条从顶点A到顶点B的路径,那么在序列中顶点A出现在顶点B的前面,如下图:

显然它是DAG图,那么如何进行拓扑排序那?

1.从DAG途中选择一个没有前驱(即入度为0)的顶点并输出2.从图中删除该顶点和所有以它为起点的有向边。3.重复1和2直到当前DAG图为空或当前途中不存在无前驱的顶点为止。后一种情况说明有向图中必然存在环。

最终,得到拓扑排序的结果是{1,2,4,3,5}

二、C3算法解析

  1. 在python2中,默认选择深度优先的算法查找,只要继承object变成新式类才能广度优先,使用inspect.getmro()查看mro顺序, 在python3中直接 类.__mro__查看

import inspect
class A:def show(self):print "A.show()"
​
class B(A): pass
class C(A):def show(self):print "C.show()"
class D(B, C): pass
print inspect.getmro(D)  #(<class __main__.D at 0x105f0a6d0>, <class __main__.B at 0x105f0a600>, <class __main__.A at 0x105f0a668>, <class __main__.C at 0x105f0a738>)
print x.show()  # A.show()

python调用mro的方法

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

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

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

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

    算法详解:C3 算法:MRO是一个有序列表L,在类被创建时就计算出来。

    L(Child(Base1,Base2))= [ Child + merge( L(Base1),L(Base2),Base1Base2 )]L(object)= [ object ]规则:L的性质:结果为列表,列表中至少有一个元素即类自己。+: 添加到列表的末尾,即 [ A + B ] = [ A,B ]① 如果列表空则结束,非空,读merge中第一个列表的表头,
    ② 查看该表头是否在merge中所有列表的表尾中。
    ②-->③ 不在,则放入最终的L中,并从merge中的所有列表中删除,然后回到①中
    ②-->④ 在,查看当前列表是否是merge中的最后一个列表
    ④-->⑤ 不是,跳过当前列表,读merge中下一个列表的表头,然后回到 ②中
    ④-->⑥ 是,异常。类定义失败。# 表头: 列表的第一个元素 (列表:ABC,那么表头就是A,B和C就是表尾)
    # 表尾: 列表中表头以外的元素集合(可以为空)

    C3算法公式

    L(D) = L(D(O))= D + merge(L(O))= D + O= [D,O]
    L(B) = L(B(D,E))= B + merge(L(D) , L(E))= B + merge(DO , EO) # 第一个列表DO的表头D,其他列表比如EO的表尾都不含有D,所以可以将D提出来,即D是合法表头= B + D + merge(O , EO) #从第一个开始表头是O,但是后面的列表EO的表尾中含有O所以O是不合法的,所以跳到下一个列表EO= B + D + E + merge(O , O)= [B,D,E,O]
    同理:
    L(C) = [C,E,F,O]
    ​
    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]

    运算过程

三、C3算法例子

L(G)=L(G(o))=G + merge(L(o))=G + o=[G,o]
L(F)=L(F(G(o)))=F + merge(L(G))=F + Go=[F,G,o]
L(B)=L(B(F(G(o))))=B + merge(L(F(G(o))))=[B,F,G,o]
# 同理    L(E)=L(E(o)) =[E,o]L(C)=L(C(E(o))) = [C,E,o]L(D)=L(D(G(o))) =[D,G,o]L(A(B,C,D))=A +merge(L(B),L(C),L(D),BCD)=A +merge(BFGo,CEo,DGo,BCD) # B合法,实在第一元素,且也是尾部第一=A+B+merge(FGo,CEo,DGo,CD) # F合法,不再其他中出现=A+B+F+merge(Go,CEo,DGo,CD) # G不合法,出现两次,跳到下一个列表即第二个中,C满足=A+B+F+C+merge(Go,Eo,DGo,D) # E合格=A+B+F+C+E+merge(Go,o,DGo,D) # 跳至第三列,D满足=A+B+F+C+E+D+merge(Go,o,Go) # 目前Go为尾,所以G合法=A+B+F+C+E+D+G+merge(o,o,o)=A+B+F+C+E+D+G+o

运算过程

L(G)=L(G(o))=[G,o]
L(E)=L(E(G(o)))=E +merge(L(G(o)))=E+[G,o]=[E,G,o]
L(D)=L(D(o))=[D,o]
L(F)=L(F(o))=[F,o]
L(B)=L(B(D,E))=B+merge(L(D),L(E),DE)=B+merge(Do,EGo,DE) #D 合格=B +D +merge(o,EGo,E) # E合格=B +D + E +merge(G,o,)= [B,D,E,G,o]
L(C)=L(C(D,F))=C+merge(L(D),L(F),DF)=C+merge(Do,Fo,DF) #D 合法=C+D+merge(o,Fo,F)  # F合法=C+D+F+merge(o)=[C,D,F,o]
L(A)=L(A(B,C))=A+merge(L(B),L(C),BC) =A +merge(BDEGo,CDFo,BC)  #B合法=A + B+merge(DEGo,CDFo,C)  # D不合法,看第二元素C合格=A + B+C+merge(DEGo,DFo,) #D合格=A + B+C+D+merge(EGo,Fo,)# E合格=A + B+C+D+E+merge(Go,Fo,)=A + B+C+D+E+G+F+o=[A,B,C,D,E,G,F,o]

运算代码

L(F)=L(F(o))=[F,o]
L(G)=L(G(o))=[G,o]
L(D(F(o)))=[D,F,o] # 因为单向所以简单
L(E(G(o)))=[E,G,o]
L(B)=L(B(D,E))=B+merge(L(D),L(E))=B+merge(DFo,EGo,DE) # D合格=B+D+merge(Fo,EGo,E)  #F合格=B+D+F+merge(o,EGo,E)  # o不合格,E合格=B+D+F+E+merge(o,Go,) # G合格=[B,D,F,E,G,o]
L(C)=L(C(E(G(o))))=C +merge(L(E))=[C,E,G,o]
L(A)=L(A(B,C))=A+merge(L(B)+L(C))=A+merge(BDFEGo,CEGo,BC) #B合格=A+B+merge(DFEGo,CEGo,C) #D 合格=A+B+D+merge(FEGo,CEGo,C) #F合格=A+B+D+F+merge(EGo,CEGo,C) #E不合格 C合理=A+B+D+F+C+merge(EGo,EGo,) # 后面都一样了所以直接写= [A,B,D,F,C,E,G,o]

运算代码

 

四、多继承例子:

class A(object):def foo(self):print('A foo')def bar(self):print('A bar')
​
class B(object):def foo(self):print('B foo')def bar(self):print('B bar')
​
class C1(A):pass
​
class C2(B):def bar(self):print('C2-bar')
​
class D(C1,C2):pass
​
if __name__ == '__main__':print(D.__mro__)d=D() #  (<class '__main__.D'>, <class '__main__.C1'>, <class '__main__.A'>, <class '__main__.C2'>, <class '__main__.B'>, <class 'object'>)d.foo() # A food.bar()  # A bar# 讲解:
#找到入度为0的顶点,只有一个D,拿D,剪掉D相关的边
#得到两个入度为0的顶点(C1,C2),根据最左原则,拿C1,剪掉C1相关的边,这时候序列为{D,C1}
#接着看,入度为0的顶点有两个(A,C1),根据最左原则,拿A,剪掉A相关的边,这时候序列为{D,C1,A}
#接着看,入度为0的顶点为C2,拿C2,剪掉C2相关的边,这时候序列为{D,C1,A,C2}
#继续,入度为0的顶点为B,拿B,剪掉B相关的边,最后还有一个object
#所以最后的序列为{D,C1,A,C2,B,object}
#以上参考:https://www.jianshu.com/p/c9a0b055947b (感谢)

多继承讲解

五、例题

# 判断下列题的运行结果
class Foo:def __init__(self):  # 来父类初始化,但是slef的本身有func函数
             self.func()def func(self):print(‘in foo’)
class Son(Foo):def func(self):print(‘in son’)
Son()     # 'in son'

例题


转载于:https://www.cnblogs.com/double-W/p/10610714.html

Python多继承的C3算法相关推荐

  1. python之多继承广度优先C3算法原理通俗易懂的讲解

    python多继承比较复杂,python2的多继承查找顺序是深度优先,pyhon3的多继承查找顺序是采取C3算法的广度优先. C3算法原理: python解释器每遇到一个类就会按广度优先的原则将其父类 ...

  2. python 多继承与super使用详解_Python super()方法、多继承以及MRO顺序

    仅供学习,转载请注明出处 单独调用父类的方法 需求:编写一个类,然后再写一个子类进行继承,使用子类去调用父类的方法1. 使用方法1打印: 胖子老板,来包槟榔. 那么先写一个胖子老板的父类,执行一下: ...

  3. python新式类c3算法_Python 新式类继承关系的 C3 算法(Python 2.3 的方法解析顺序,MRO)...

    Python 新式类继承关系的 C3 算法(Python 2.3 的方法解析顺序,MRO) 翻译:刘硕 摘要:本文档面向于想要了解Python 2.3版本中 C3 方法解析顺序的 Python程序开发 ...

  4. python新式类c3算法_python中的MRO和C3算法

    一. 经典类和新式类 1.python多继承 在继承关系中,python子类自动用友父类中除了私有属性外的其他所有内容.python支持多继承.一个类可以拥有多个父类 2.python2和python ...

  5. python新式类c3算法_Python新式类的方法解析顺序MRO与Super

    新式类与经典类的方法解析顺序 MOR(方法解析顺序) 经典类:深度优先 DFS python3以前 新式类:广度优先 python2.2 新式类:广度优先的C3算法实现(拓扑排序) BFS pytho ...

  6. python mro c3_Python 19 MRO和C3算法

    1.python经典类的MRO 经典类的MRO class A: pass class B(A): pass class C(A): pass class D(B, C): pass class E: ...

  7. 多继承、经典类与新式类、新式类的C3算法详解

    多继承Python2版本class A(object) ---> 新式类class B ---> 经典类 Python3版本默认都是新式类 经典类和新式类的不同在于多继承时继承的顺序不同经 ...

  8. 继承,经典类与新式类的MRO,C3算法,super

    #继承 class JiaoFu:def qd(self):print("教父带你祈祷") class Fu:def msj(self):print("alex喜欢msj ...

  9. python mro c3_绝地求生辅助_Python的多继续问题-MRO和C3算法

    博弈论--两人取子游戏与威佐夫博弈,隐藏在背后的黄金分割dnf辅助Python 中的方式剖析顺序(Method Resolution Order, MRO)界说了多继续存在时 Python 注释器查找 ...

最新文章

  1. 继承的综合运用《Point类派生出Circle类而且进行各种操作》
  2. ABAddressBookSave关于保存到通讯录失败的问题
  3. 2021“MINIEYE杯”中国大学生算法设计超级联赛(5)Random Walk 2(推式子+矩阵逆+矩阵乘)
  4. 【Python】我的第一个EXE程序
  5. 请问asp.net网页里能显示tiff格式的图片吗?
  6. unix grep命令_Linux / UNIX中的Grep命令
  7. python连续质数计算代码分析,素性测试的Miller-Rabin算法完全解析 (C语言实现、Python实现)...
  8. 32G内存oracle内核设置,浅谈安装ORACLE时在Linux上设置内核参数的含义
  9. [转]使用 HTML5 索引型数据库的待办事项简要列表
  10. 右键新建文件夹_教你修改Windows万年不变的黄色文件夹,让文件也不枯燥
  11. python的pyaudio教程入门_Python音频操作工具PyAudio上手教程
  12. iOS 实现时间线列表效果
  13. 中信银行总行信息科技部的面试(校招)
  14. 软件定义产品——软件定义汽车技术路线(SDV)
  15. 深入理解MOT评价指标
  16. EditText自动弹出输入法问题
  17. 《卓有成效的管理者》笔记,第一章 卓有成效是可以学会的
  18. Windows驱动开发WDM (1) - 基本结构
  19. 学术写作笔记(3):引言
  20. DeepLabCut AI Residency

热门文章

  1. Python提取MP3
  2. Linux NFS文件系统挂载
  3. VS2013配置VTK7.1.1
  4. 中医移动医疗百花齐放,持续探索盈利模式
  5. abaqus Linux 中文,SIMULIA ABAQUS 2016.0 Win64 Linux64 2DVD工程模拟的有限元
  6. 2022,上榜的实时操作系统有哪些?
  7. MAC电脑无法登录 H3C inode 的解决办法
  8. 计算机网络学习笔记16--网络层网络层服务模型
  9. Cantor三分集为啥不能在Myeclipse上完美实现呢?
  10. 用户信息管理系统(Web实践项目)