Python多重继承顺序---C3算法
什么是多重继承C3算法
- MRO即 method resolution order (方法解释顺序),主要用于在多继承时判断属性的路径(来自于哪个类)。
- 在python2.2版本中,算法基本思想是根据每个祖先类的继承结构,编译出一张列表,包括搜索到的类,按策略删除重复的。但是,在维护单调性方面失败过(顺序保存)。C3是1996年首次被提出。在python2.3及后续版本中,C3被选定为默认的解析算法。C3线性表是用于获取多重继承下继承顺序的一种算法。
- C3算法最早被提出是用于Lisp的,应用在Python中是为了解决原来基于深度优先搜索算法不满足本地优先级,和单调性的问题。
(本地优先级:指声明时父类的顺序,比如C(A,B),如果访问C类对象属性时,应该根据声明顺序,优先查找A类,然后再查找B类。
单调性:如果在C的解析顺序中,A排在B的前面,那么在C的所有子类里,也必须满足这个顺序。)
c3算法方法
一个类的C3线性表,是由两部分进行merge操作得到的,第一部分是是它所有父类的C3线性表(parents' linearizations),第二部分是它所有父类组成的列表(parents list)。后者其实是局部的优先级列表。
L(Child(Base1,Base2)) = [ Child + merge( L(Base1) , L(Base2) , Base1Base2 )]
L(object) = [ object ]
所谓merge操作,遵循以下原则:表的首个元素不可以出现在其他地方,如果出现了这样的情形,那么就要将该元素全部移出,放到产出列表(output list)中。如果循环进行这一操作,就可以把所有的表逐步移出,逐步扩张产出表,最后得到一个
纯粹的产出表。这个产出表就是最后的C3线性表。
merge: ① 如果列表空则结束,非空 读merge中第一个列表的表头,
② 查看该表头是否在 merge中所有列表的表尾中。
②-->③ 不在,则 放入 最终的L中,并从merge中的所有列表中删除,然后 回到①中
②-->④ 在,查看 当前列表是否是merge中的最后一个列表
④-->⑤ 不是 ,跳过当前列表,读merge中下一个列表的表头,然后 回到 ②中
④-->⑥ 是,异常。类定义失败。
表头: 列表的第一个元素 (列表:ABC,那么表头就是A,B和C就是表尾)
表尾: 列表中表头以外的元素集合(可以为空)
merge 简单的说即寻找合法表头(也就是不在表尾中的表头),如果所有表中都未找到合法表头则异常。
C3算法的三大重要属性:
1.前趋图。作为有向无环图,找不到任何的循环,通常用前趋图来理解程序的依赖关系。
2.保持局部的优先次序。
3.单调性。
举个例子:

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的数组列表,可以梳理清楚子类执行过程中向上执行的顺序
Python多重继承顺序---C3算法的更多相关文章
- python MRO及c3算法
1. 了解python2和python3类的区别 python2在2.3之前使用的是经典类, 2.3之后, 使用的是新式类 2. 经典类的MRO 树形结构的深度优先遍历 -> 树形结构遍历 cl ...
- python --- 21 MRO C3算法
一.python2.2之前用的是 经典类的MRO继承 ①深度递归继承 从左到右 ,一条路走到黑 ②广度继承 一层一层的继承 深度继承时 为 R 1 2 3 4 ...
- Python多继承C3算法
Python3 多继承的MRO算法选择.MRO(Method Resolution Order):方法解析顺序. Python3 只保留了C3算法! C3算法解析: 1.C3算法解析 C3算法:MRO ...
- python学习笔记:第20天 多继承、MRO C3算法
目录 一.多继承 二.旧式类的MRO 三.新式类的MRO 四.super 一.多继承 之前已经学习过了继承,当出现了x是⼀种y的的时候,就可以使⽤继承关系,即"is-a" 关系.在 ...
- 关于Python类的多继承中的__mro__属性使用的C3算法以及继承顺序解释
刚刚学到类的多继承这个环节,当子类继承多个父类时,调用的父类中的方法具体是哪一个我们无从得知,为此,在Python中有函数__mro__来表示方法解析顺序. 当前Python3.x的类多重继承算法用的 ...
- Python新式类继承的C3算法
在Python的新式类中,方法解析顺序并非是广度优先的算法,而是采用C3算法,只是在某些情况下,C3算法的结果恰巧符合广度优先算法的结果. 可以通过代码来验证下: class NewStyleClas ...
- python全栈开发day103-python垃圾回收机制、mro和c3算法解析、跨域jsonp\CORS、Content-Type组件
Python垃圾回收 -- 引用计数 -- Python为每个对象维护一个引用计数 -- 当引用计数为0的 代表这个对象为垃圾 -- 标记清除 -- 解决孤立的循环引用 -- 标记根节点和可达对象 - ...
- python之MRO和C3算法
python2类和python3类的区别pyhon2中才分新式类与经典类,python3中统一都是新式类Python 2.x中默认都是经典类,只有显式继承了object才是新式类python 3.x中 ...
- python学习 day20 (3月27日)----(单继承多继承c3算法)
继承: 提高代码的重用性,减少了代码的冗余 这两个写法是一样的 Wa('青蛙').walk() #青蛙 can walk wa = Wa('青蛙') wa.walk() #青蛙 can walk 1. ...
随机推荐
- Python yield使用浅析
yield可将一个函数变成生成器,每次调用时,返回yield的结果,下次迭代时,从yield 下条语句开始执行. 一个典型的例子,斐波拉切数列: def fab(max): n, a, b = 0, ...
- Python查找最新测试报告到邮件功能
#coding=utf-8 import smtplib from email.mime.text import MIMEText import unittest import HTMLTestRun ...
- What Are You Talking About (map)
Ignatius is so lucky that he met a Martian yesterday. But he didn't know the language the Martians u ...
- java方法重载和重写
1.java的方法重载和重写,表示两种不同的类型.this关键字,出现在类的构造方法中,代表使用该构造方法所创建的对象.,this可以出现在实例方法中核构造方法中.但是不能出现在类方法中.实例方法只能 ...
- PXE+HTTP+TFTP+Kickstart实现无人值守部署centos6.10
在联网的状态下安装所需软件: Shell> yum install dhcp httpd tftp-server xinetd syslinux system-config-kickstart ...
- AI学习吧-Redis操作-事务、订阅
事务 #首先启动redis服务端和客户端:#关于事务,数据库中的事务指的是逻辑上的一组操作,这组操作要么都执行成功要么不执行成功,出现异常会回滚到初始状态. 在代码中加入xxx,代码报错的话,不会执行 ...
- 20165206第4次实验《Android程序设计》实验报告
20165206第4次实验<Android程序设计>实验报告 一.实验报告封面 课程:Java程序设计 班级:1652班 姓名:韩啸 学号:20165206 指导教师:娄嘉鹏 实验日期:2 ...
- The.Glory.of.Innovation 创新之路2科学基石
犹太民族很早就确立了他们的生存法则:资源.土地,以及一切有形的东西都会消失,一个人最重要的财富是自己的头脑.是知识.是创造. 有些选择是被动的,有些选择是主动的,一旦决心要把技术变成自己的,独立的 ...
- OpenCV trackbar 避免使用全局变量
OpenCV trackbar 避免使用全局变量 在OpenCV中使用trackbar是交互式地图像处理的一种方式,例如用于图像阈值分割,用户可以一边调整阈值一边看效果.但是很不幸,绝大多数教程上使用 ...
- 交换机的vlan文章
https://blog.csdn.net/standmyground/article/details/3933364 大家知道,交换机会把广播报文(目的mac地址全1的报文)和未知单播报文从所有端口 ...