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相关推荐

  1. mro python_用python实现MRO算法

    引子: 如图反映了python3中,几个类的继承关系和查找顺序.对于类A,其查找顺序为:A,B,E,C,F,D,G,(Object),这并不是一个简单的深度优先或广度优先的规律.那么这个顺序到底是如何 ...

  2. Python中MRO

    MRO(方法解析顺序) 当有多重继承时,基于"从左到右,深度优先原则": class CommonBase():def Method(self):print('CommonBase ...

  3. python多继承顺序_Python多重继承方法解析顺序(MRO构建算法)

    分界 python的MRO算法有新旧两种,但并不是以python2和python3为界,具体的分隔为:在python2中如果定义类的时候没有指定父类是object,即定义为 class A: pass ...

  4. Python面向对象中super用法与MRO机制

    1. 引言 最近在研究django rest_framework的源码,老是遇到super,搞得一团蒙,多番查看各路大神博客,总算明白了一点,今天做一点总结. 2. 为什么要用super 1)让代码维 ...

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

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

  6. python中的MRO与多继承

    相关概念: MRO:Method Resolution Order,即方法解析顺序,是python中用于处理二义性问题的算法 二义性: python支持多继承,多继承的语言往往会遇到以下两类二义性的问 ...

  7. 深入super,看Python如何解决钻石继承难题

    1.   Python的继承以及调用父类成员 python子类调用父类成员有2种方法,分别是普通方法和super方法 假设Base是基类 class Base(object):def __init__ ...

  8. python类的方法三种访问权_Python基础33-面向对象(继承资源(属性与方法)的使用注意)...

    在Python中, 继承是指子类对父类资源的使用权 1 继承-属性与方法的使用权限 1.1 测试属性与方法分别如下 公有属性/方法 受保护属性/方法 私有属性/方法 class Animal: a = ...

  9. python类的继承super方法_Python类的继承super相关原理解析

    看了网上许多关于super.mro.C3的介绍感觉没有一份很容易初学者理解的文档,直接看C3算法的话,比较难理解,也没必要,如果掌握一套规律的话,会轻松许多.我将网上这些博主的文章进行一个梳理总结,最 ...

  10. mro python_Python新式类的方法解析顺序MRO与Super

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

最新文章

  1. python3+ 解决写入中文乱码的问题
  2. 算法导论——lec 10 图的基本算法及应用
  3. 职称计算机windows 7,2017职称计算机考试Windows训练题
  4. 【Python实现网络爬虫】Scrapy爬取网易新闻(仅供学习交流使用!)
  5. jMeter 打开项目时遇到错误消息 CannotResolveClassException: com.blazemeter.jmeter.RandomCSVDataSetConfig
  6. hash算法_到底什么是Hash?Hash算法的原理和实际应用讲解
  7. 主键约束 mysql
  8. cad中简单流程图制作_Excel vba 简单制作流程图方法介绍
  9. JAVA 基础语法(一)——变量以及基本数据类型
  10. python计算目标文件夹中各文件的GC含量
  11. linux2t硬盘格式化时间,linux下大于2T硬盘格式化方法
  12. 简单说说路由器和交换机的区别
  13. cocos 添加遮罩后白屏_Cocos2dx3.2 Crazy Tetris 由于遮罩引起的部分手机白屏
  14. bootstrap fileupload 使用详解~~
  15. c# 数字转大写中文
  16. 全新视角!带你一文读懂ChatGPT!
  17. android 常用机型尺寸_Android中获取手机屏幕大小的方法
  18. 互联网晚报 | 8月15日 星期日 | 第四范式申请港交所上市;招行私人银行客户突破11万户;特斯拉CEO马斯克去年总薪酬为零...
  19. 学习与思考,李敖有话说
  20. 九章算术 八:《方程》

热门文章

  1. 电子地图有比例尺吗?
  2. R语言绘制中国地图,增加指北针、比例尺和九段线区域小图
  3. docker端口映射但外网无法访问解决方案
  4. codevs 1253 超级市场 DP 解题报告
  5. 化学到底是不是一个好专业?该不该转行?————试图以此文终结所有相关讨论...
  6. 系统集成项目管理工程师06《项目成本管理》
  7. 大三老狗的前端实习半年心得-经验分享
  8. 注册表怎么用计算机管理打开,如何打开注册表,详细教您如何打开电脑注册表管理器...
  9. 三角函数π/2转化_数学集训营 | NO.16 任意角的三角函数之必考点
  10. 为什么你996猝死,你老板007都没事?