python多重继承新算法C3介绍


Posted in Python onSeptember 28, 2014

mro即 method resolution order (方法解释顺序),主要用于在多继承时判断属性的路径(来自于哪个类)。

在python2.2版本中,算法基本思想是根据每个祖先类的继承结构,编译出一张列表,包括搜索到的类,按策略删除重复的。但是,在维护单调性方面失败过(顺序保存),所以从2.3版本,采用了新算法C3。

为什么采用C3算法

C3算法最早被提出是用于Lisp的,应用在Python中是为了解决原来基于深度优先搜索算法不满足本地优先级,和单调性的问题。

本地优先级:指声明时父类的顺序,比如C(A,B),如果访问C类对象属性时,应该根据声明顺序,优先查找A类,然后再查找B类。

单调性:如果在C的解析顺序中,A排在B的前面,那么在C的所有子类里,也必须满足这个顺序。

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])
merge操作就是C3算法的核心。

遍历执行merge操作的序列,如果一个序列的第一个元素,是其他序列中的第一个元素,或不在其他序列出现,则从所有执行merge操作序列中删除这个元素,合并到当前的mro中。

merge操作后的序列,继续执行merge操作,直到merge操作的序列为空。

如果merge操作的序列无法为空,则说明不合法。

例子:

class A(O):pass

class B(O):pass

class C(O):pass

class E(A,B):pass

class F(B,C):pass

class G(E,F):pass

A、B、C都继承至一个基类,所以mro序列依次为[A,O]、[B,O]、[C,O]

mro(E) = [E] + merge(mro(A), mro(B), [A,B])

       = [E] + merge([A,O], [B,O], [A,B])

执行merge操作的序列为[A,O]、[B,O]、[A,B]

A是序列[A,O]中的第一个元素,在序列[B,O]中不出现,在序列[A,B]中也是第一个元素,所以从执行merge操作的序列([A,O]、[B,O]、[A,B])中删除A,合并到当前mro,[E]中。
mro(E) = [E,A] + merge([O], [B,O], [B])

再执行merge操作,O是序列[O]中的第一个元素,但O在序列[B,O]中出现并且不是其中第一个元素。继续查看[B,O]的第一个元素B,B满足条件,所以从执行merge操作的序列中删除B,合并到[E, A]中。

mro(E) = [E,A,B] + merge([O], [O])

       = [E,A,B,O]

实现C3算法的代码

#-*- encoding:GBK -*-#  

def mro_C3(*cls):  

        if len(cls)==1:  

            if not cls[0].__bases__:  

                return  cls  

            else:  

                return cls+ mro_C3(*cls[0].__bases__)  

        else:  

            seqs = [list(mro_C3(C)) for C in cls ] +[list(cls)]  

            res = []  

            while True:  

              non_empty = list(filter(None, seqs))  

              if not non_empty:  

                  return tuple(res)  

              for seq in non_empty:  

                  candidate = seq[0]  

                  not_head = [s for s in non_empty if candidate in s[1:]]  

                  if not_head:  

                      candidate = None  

                  else:  

                      break  

              if not candidate:  

                  raise TypeError("inconsistent hierarchy, no C3 MRO is possible")  

              res.append(candidate)  

              for seq in non_empty:  

                  if seq[0] == candidate:  

                      del seq[0]

Python 相关文章推荐
python魔法方法-属性转换和类的表示详解
Jul 22 Python
Mac中升级Python2.7到Python3.5步骤详解
Apr 27 Python
Python cookbook(数据结构与算法)同时对数据做转换和换算处理操作示例
Mar 23 Python
解决pycharm界面不能显示中文的问题
May 23 Python
详解Python 协程的详细用法使用和例子
Jun 15 Python
Django管理员账号和密码忘记的完美解决方法
Dec 06 Python
Python Matplotlib 基于networkx画关系网络图
Jul 10 Python
Python3操作Excel文件(读写)的简单实例
Sep 02 Python
python实现word文档批量转成自定义格式的excel文档的思路及实例代码
Feb 21 Python
Spring @Enable模块驱动原理及使用实例
Jun 23 Python
Python执行时间的几种计算方法
Jul 31 Python
python time()的实例用法
Nov 03 Python
wxPython窗口的继承机制实例分析
Sep 28 #Python
wxPython框架类和面板类的使用实例
Sep 28 #Python
Python的加密模块md5、sha、crypt使用实例
Sep 28 #Python
wxPython学习之主框架实例
Sep 28 #Python
python实现得到一个给定类的虚函数
Sep 28 #Python
python实现根据图标提取分类应用程序实例
Sep 28 #Python
wxPython事件驱动实例详解
Sep 28 #Python
You might like
thinkPHP框架动态配置用法实例分析
2018/06/14 PHP
PHP实现简易计算器功能
2020/08/28 PHP
JS 表单验证大全
2011/11/23 Javascript
详解JavaScript函数对象
2015/11/15 Javascript
jquery操作select元素和option的实例代码
2016/02/03 Javascript
浅谈Javascript中的函数、this以及原型
2016/10/09 Javascript
8 行 Node.js 代码实现代理服务器
2016/12/05 Javascript
Bootstrap和Java分页实例第一篇
2016/12/23 Javascript
vue中如何实现pdf文件预览的方法
2018/07/12 Javascript
基于webpack4+vue-cli3项目实现换肤功能
2019/07/17 Javascript
[01:01:35]Optic vs paiN 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
Python使用Flask框架同时上传多个文件的方法
2015/03/21 Python
使用Python的内建模块collections的教程
2015/04/28 Python
微信跳一跳python自动代码解读1.0
2018/01/12 Python
Django 中使用流响应处理视频的方法
2018/07/20 Python
Python高级特性——详解多维数组切片(Slice)
2019/11/26 Python
如何在python开发工具PyCharm中搭建QtPy环境(教程详解)
2020/02/04 Python
python画图常规设置方式
2020/03/05 Python
Python3 io文本及原始流I/O工具用法详解
2020/03/23 Python
Keras预训练的ImageNet模型实现分类操作
2020/07/07 Python
使用Python封装excel操作指南
2021/01/29 Python
html5+css3气泡组件的实现
2014/11/21 HTML / CSS
CSS3弹性盒模型flex box快速入门心得(必看篇)
2016/05/24 HTML / CSS
关于webview适配H5上传照片或者视频文件的方法
2020/11/04 HTML / CSS
Mio Skincare中文官网:肌肤和身体护理
2016/10/26 全球购物
英国最受欢迎的价格比较网站之一:MoneySuperMarket
2018/12/19 全球购物
摄影实习自我鉴定
2013/09/20 职场文书
技术总监岗位职责
2013/12/05 职场文书
教师申诉制度
2014/01/29 职场文书
酒店营销策划方案
2014/02/07 职场文书
日语专业毕业生自荐书
2014/06/18 职场文书
中华魂放飞梦想演讲稿
2014/08/26 职场文书
公务员四风问题对照检查材料整改措施
2014/09/26 职场文书
2015年大学生实习评语
2015/03/25 职场文书
2016年校长新年寄语
2015/08/17 职场文书
Python中的xlrd模块使用整理
2021/06/15 Python