Python的MRO
Python的MRO即Method Resolution Order(方法解析顺序),即在调用方法时,会对当前类以及所有的基类进行一个搜索,以确定该方法之所在,而这个搜索的顺序就是MRO。
在Python2.3之前,MRO的实现是基于DFS的,而在Python2.3以后MRO的实现是基于C3算法(我这里两种算法的具体实现都不详述)。
C3算法最早被提出是用于Lisp的,应用在Python中是为了解决原来基于深度优先搜索算法不满足本地优先级,和单调性的问题。
本地优先级:指声明时父类的顺序,比如C(A,B),如果访问C类对象属性时,应该根据声明顺序,优先查找A类,然后再查找B类。
单调性:如果在C的解析顺序中,A排在B的前面,那么在C的所有子类里,也必须满足这个顺序。
总的来说,一个类的 MRO 列表就是合并所有父类的 MRO 列表,并遵循以下三条原则:
子类永远在父类前面
如果有多个父类,会根据它们在列表中的顺序被检查
如果对下一个类存在两个合法的选择,选择第一个父类
下面我用图解的形式来表现三条原则并计算出MRO(只是说这种方式可以手算出MRO,而不是说这是C3算法的具体实现方式):
首先看以下代码
class F:passclass E:passclass D:passclass B(D,E):passclass C(D,F):passclass A(B,C):pass
然后我们构建一个继承顺序图
即让子类用箭头指向父类,逐层排列成类似下图这种
遇到多继承则按代码中继承列表的顺序从左往右写。如果有多个子类继承了同一个父类,那么这个父类则放在它能够出现的所有位置中最左的位置(注意:如下图中那样,D既可以放在B的左上方,又可以放在C的左上方,这种情况下,我们选择放在B的左上方,因为这样D在其所在层更加靠左),然后让这些子类指向它,就像下图中类D那样。
然后依据代码就可以形成上面的这个继承顺序图。(在python中,任何类默认都是继承自object类的,所以让最上层的D、E、F指向object。当然,你也可以选择在画图的时候将A,B,C等等所有类都画一个指向object的箭头,但随着以下方法的进行,其实这两种画法结果是一样的。)
接下来,我们就开始算出相应的MRO。即需遵循图里面的广度优先原则进行遍历(在广度优先原则的前提下又优先遍历左边的):
首先寻找整个图中入度为0的,也就是A,那么A也就成为MRO中的第一个。
然后我们去掉图中的A节点以及与A相关的连线,再寻找入度为0的点,这时有B和C两个节点,我们选择最左边的点即B。选完左边的B点后,再选右边的C点,这样B和C也就跟着进入了MRO序列,现在MRO序列为{A,B,C}。(注意每次层次遍历一定要把那一层选完才能选下一层,不能在没有选C之前跳到选E)
然后去掉B和C以及与它们相关的连线,这时候入度为0的也就是D、E、F了,依次选择,使D、E、F进入MRO序列。
最后也就使得object进入MRO序列。
以上的MRO序列也就是{ABCDEFobject}
使用 类名.mro()可以查阅其MRO表:
最后说一下super
一般都会说,在类中用super()可以取父类的成员变量和成员方法
更具体地讲是super(cls, inst) ,它获得的是类cls 在实例inst的 MRO 列表中的下一个类。(也就说是实例或者说对象I有一个MRO列表,这个列表中有类C,而我们获取的就是类C的后面的那个类)
工作原型为:
def super(cls, inst):mro = inst.__class__.mro()return mro[mro.index(cls) + 1]
这里需要注意的是inst处是一个实例,而不是一个未实例化的类。
故而可以在类里super(B,self).方法 或者
在类外x=C() 然后super(B,x).方法
Python的MRO相关推荐
- mro python_用python实现MRO算法
引子: 如图反映了python3中,几个类的继承关系和查找顺序.对于类A,其查找顺序为:A,B,E,C,F,D,G,(Object),这并不是一个简单的深度优先或广度优先的规律.那么这个顺序到底是如何 ...
- Python中MRO
MRO(方法解析顺序) 当有多重继承时,基于"从左到右,深度优先原则": class CommonBase():def Method(self):print('CommonBase ...
- python多继承顺序_Python多重继承方法解析顺序(MRO构建算法)
分界 python的MRO算法有新旧两种,但并不是以python2和python3为界,具体的分隔为:在python2中如果定义类的时候没有指定父类是object,即定义为 class A: pass ...
- Python面向对象中super用法与MRO机制
1. 引言 最近在研究django rest_framework的源码,老是遇到super,搞得一团蒙,多番查看各路大神博客,总算明白了一点,今天做一点总结. 2. 为什么要用super 1)让代码维 ...
- python新式类c3算法_Python新式类的方法解析顺序MRO与Super
新式类与经典类的方法解析顺序 MOR(方法解析顺序) 经典类:深度优先 DFS python3以前 新式类:广度优先 python2.2 新式类:广度优先的C3算法实现(拓扑排序) BFS pytho ...
- python中的MRO与多继承
相关概念: MRO:Method Resolution Order,即方法解析顺序,是python中用于处理二义性问题的算法 二义性: python支持多继承,多继承的语言往往会遇到以下两类二义性的问 ...
- 深入super,看Python如何解决钻石继承难题
1. Python的继承以及调用父类成员 python子类调用父类成员有2种方法,分别是普通方法和super方法 假设Base是基类 class Base(object):def __init__ ...
- python类的方法三种访问权_Python基础33-面向对象(继承资源(属性与方法)的使用注意)...
在Python中, 继承是指子类对父类资源的使用权 1 继承-属性与方法的使用权限 1.1 测试属性与方法分别如下 公有属性/方法 受保护属性/方法 私有属性/方法 class Animal: a = ...
- python类的继承super方法_Python类的继承super相关原理解析
看了网上许多关于super.mro.C3的介绍感觉没有一份很容易初学者理解的文档,直接看C3算法的话,比较难理解,也没必要,如果掌握一套规律的话,会轻松许多.我将网上这些博主的文章进行一个梳理总结,最 ...
- mro python_Python新式类的方法解析顺序MRO与Super
新式类与经典类的方法解析顺序 MOR(方法解析顺序) 经典类:深度优先 DFS python3以前 新式类:广度优先 python2.2 新式类:广度优先的C3算法实现(拓扑排序) BFS pytho ...
最新文章
- 【集合论】容斥原理 ( 复杂示例 )
- 基于ServletJsp的网上书店设计(二)
- 常见程序设计及编程开发问题解答
- Linux I2C核心、总线与设备驱动(一)
- 23种设计模式[1]:单例模式
- microsoft visual studio遇到了问题,需要关闭
- python有趣的代码-python菜鸟教程,python好玩又简单的代码
- 传智播客 sklearn数据集与机器学习组成
- 令人魂牵梦绕的香格里拉
- Oracle数据库安装教程
- 知云文献翻译出现乱码的解决方式
- 微型计算机原理及应用 湖南大学,2015年微机原理及其应用-湖南大学.doc
- 【软件工程】实验七:建立功能模型--自行车租赁管理系统
- Symbian S60第三版软件精选介绍
- Calendar计算两个日期相差几个月
- Python爬虫分析,全国结婚率连续5年下降,这届年轻人,为什么不敢结婚?
- Jetpack:Room配合LiveData/Flow使用优化,Room+Flow使用原理解析。
- 2017 robotart x86_RobotArt:机器人离线编程仿真软件领航者
- Altera 的SOC器件之将自定义的IP挂在ARM硬核下(通过avalon总线),实现arm核与IP之间的通信
- 应变片信号采集--串口程序--借助python和tkinter
热门文章
- Win10系统电脑开机后显示无法登录到你的账户解决办法(亲测)
- android 手机ssh客户端,android手机ssh客户端ConnectBot
- 云台山风景区,感受人生最美的风景
- 数据挖掘——关联分析Apriori算法
- 元器件——瞬态抑制二极管TVS的选型应用总结(TVS的应用、TVS常用参数、TVS选型注意点、单向和双向TVS)
- uptime查看服务器负载详解
- ASEMI快恢复二极管US1M参数,US1M恢复时间,US1M压降
- 触摸一体机android,触摸一体机的系统是安卓系统还是Windows系统?
- 【Oracle SQL】计算同比与环比(列转行进行偏移)
- 深夜的呼唤,无尽的力量