一、引入

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]

python新式类继承------C3算法的更多相关文章

  1. Python新式类继承的C3算法

    在Python的新式类中,方法解析顺序并非是广度优先的算法,而是采用C3算法,只是在某些情况下,C3算法的结果恰巧符合广度优先算法的结果. 可以通过代码来验证下: class NewStyleClas ...

  2. python中多继承C3算法研究

    在python的面向对象继承问题中,单继承简单易懂,全部接受传承类的属性,并可添加自带属性, 但是,在多继承情况下,会遇到多个被继承者的顺序问题,以及多次继承后查找前几次继承者需求属性时,可能不易发现 ...

  3. 面向对象多继承(c3算法)、网络基础和编写网络相关的程序

    一.面向对象多继承(c3算法) a.有多个父类先找左,再找右,如下示例: class A(object): pass class B(object): def f1(self): print('B') ...

  4. 面向对象多继承(C3算法)/网络编程

    https://www.cnblogs.com/aylin/p/5572104.html 一.面向对象多继承(c3算法) a.有多个父类先找左,再找右,如下示例: class A(object): p ...

  5. python学习 day20 (3月27日)----(单继承多继承c3算法)

    继承: 提高代码的重用性,减少了代码的冗余 这两个写法是一样的 Wa('青蛙').walk() #青蛙 can walk wa = Wa('青蛙') wa.walk() #青蛙 can walk 1. ...

  6. Python新式类和经典类的区别

    @Python新式类和经典类的区别 class ClassicClass(): pass class NewStyleClass(object): pass x1 = ClassicClass() x ...

  7. Python 多继承(新式类) 的mro算法

    转载自:http://www.cnblogs.com/panyinghua/p/3283831.html mro即method resolution order,主要用于在多继承时判断调的属性的路径( ...

  8. python的多继承C3(mro)算法

    多继承的继承顺序按照C3算法进行顺序继承 例一 按照深度A类从左往右有三条可继承的"路" 先按照深度优先的算法,将每一路的每一个节点加到列表中 B = [B,D,F,H] C = ...

  9. Python多继承C3算法

    Python3 多继承的MRO算法选择.MRO(Method Resolution Order):方法解析顺序. Python3 只保留了C3算法! C3算法解析: 1.C3算法解析 C3算法:MRO ...

随机推荐

  1. Maven 梳理 - 使用Maven构建多模块项目

    多模块实际案例 project |--business (核心业务) |--business-api |--business-service |--business-message |--busine ...

  2. jQuery常用方法(一)-基础

    $("p").addClass(css中定义的样式类型); 给某个元素添加样式 $("img").attr({src:"test.jpg", ...

  3. Django中的表关系实现及操作

    表关系的实现   预备知识 ORM的正向操作和反向操作: 1.正向操作:一个模型中定义了一个外键,通过该模型对该外键操作的操作叫做正向操作. 2.反向操作:被外键所关联的模型,通过该模型对外键所在模型 ...

  4. A-02 梯度下降法

    目录 梯度下降法 一.梯度下降法详解 1.1 梯度 1.2 梯度下降法和梯度上升法 1.3 梯度下降 1.4 相关概念 1.4.1 步长 1.4.2 假设函数 1.4.3 目标函数 二.梯度下降法流程 ...

  5. Mr. Rito Post Office

    あなたは離島の郵便局に勤めるプログラマである.あなたの住んでいる地域は,複数の島々からなる.各島には一つ以上の港町がある.それらに加えて他の町や村があるかもしない.ある島から別の島に向かうためには船を ...

  6. 《Java编程思想》——初始化与清理(一)读书笔记

    第一次写这个,这一章都用word写的,结果复制过来没图片....只能上传word文档了.以后改用markdown比较好 word文档地址:<Java编程思想>--初始化与清理(一)读书笔记

  7. SpringBoot2.x升级踩坑--新增Configuration property name限制

    最近公司项目在做SpringBoot的升级,在升级过程中遇到了一些问题,简单记录一下,做个分享.另外,本文中的程序只为示例代码,并非公司生产环境代码. 遇到什么问题 从SpringBoot1.x升级到 ...

  8. dll劫持破坏360

    0x01 前言 说起DLL劫持技术,相信大家都不会陌生,因为这种技术的应用比较广泛,比如木马后门的启动.破解程序的内存补丁.外挂插件的注入以及加密狗的模拟等.之所以DLL劫持技术深受黑客们的喜爱,主要 ...

  9. JSON:JSON对象和JSON数组混排的复杂字符串

    在java中的一个好用的JSON工具包:net.sf.json.JSONObject 和 net.sf.json.JSONArray 一 解析JSON对象和JSON数组类型混排的复杂字符串 举个例子: ...

  10. Qt 找不到rc.exe

    Qt在window下出现编译错误: LINK : fatal error LNK1158: 无法运行“rc.exe” 解决: 找到rc.exe的放置路径,比如我的在下面: C:\Program Fil ...