关于Python类的多继承中的__mro__属性使用的C3算法以及继承顺序解释
刚刚学到类的多继承这个环节,当子类继承多个父类时,调用的父类中的方法具体是哪一个我们无从得知,为此,在Python中有函数__mro__来表示方法解析顺序。
当前Python3.x的类多重继承算法用的是C3
MRO序列:
MRO是一个有序列表L,在类被创建时就计算出来。
通用计算公式为:mro(Child(Base1,Base2)) = [ Child ] + merge( mro(Base1), mro(Base2), [ Base1, Base2] )其中Child继承自Base1, Base2)如果类B继承类A:
这时类B的mro序列为:
mro( B ) = mro( B(A) )
= [B] + merge( mro(A) + [A] )
= [B] + merge( [A] + [A] )
= [B,A]
如果继承至多个基类:class B(A1, A2, A3 …)
这时B的mro序列为:
mro(B) = mro( B(A1, A2, A3 …) )
= [B] + merge( mro(A1), mro(A2), mro(A3) ..., [A1, A2, A3] )
= ...
计算得到的结果为列表,列表中第一个元素为自身,如上述示例[A1,A2,A3],merge操作是C3算法的核心,了解了merge操作的原理,就了解了C3算法。
merge操作:
假如计算merge( [E,O], [C,E,F,O], [C] )
取出第一个列表[E,O]的表头E,进行判断:
各个列表的表尾分别是[O], [E,F,O],E在这些表尾的集合中,因而跳过当前当前列表
取出第二个列表[C,E,F,O]的表头C,进行判断:
C不在各个列表的集合中,因而将C拿出到merge外,并从所有表头删除
merge( [E,O], [C,E,F,O], [C]) = [C] + merge( [E,O], [E,F,O] )
...
假设有如下的继承关系:

计算mro(A)的方式为:
mro(A) = mro( A(B,C) ) 原式= [A] + merge( mro(B),mro(C),[B,C] ) mro(B) = mro( B(D,E) )
= [B] + merge( mro(D), mro(E), [D,E] ) # 多继承
= [B] + merge( [D,O] , [E,O] , [D,E] ) # 单继承mro(D(O))=[D,O]
= [B,D] + merge( [O] , [E,O] , [E] ) # 拿出并删除D
= [B,D,E] + merge([O] , [O])
= [B,D,E,O] mro(C) = mro( C(E,F) )
= [C] + merge( mro(E), mro(F), [E,F] )
= [C] + merge( [E,O] , [F,O] , [E,F] )
= [C,E] + merge( [O] , [F,O] , [F] ) # 跳过O,拿出并删除
= [C,E,F] + merge([O] , [O])
= [C,E,F,O] 原式= [A] + merge( [B,D,E,O], [C,E,F,O], [B,C])
= [A,B] + merge( [D,E,O], [C,E,F,O], [C])
= [A,B,D] + merge( [E,O], [C,E,F,O], [C]) # 跳过E
= [A,B,D,C] + merge([E,O], [E,F,O])
= [A,B,D,C,E] + merge([O], [F,O]) # 跳过O #注意O即为所有类的基类object
= [A,B,D,C,E,F] + merge([O], [O])
= [A,B,D,C,E,F,O]
根据上图的继承关系:
可以得到A的mro序列为:[A,B,D,C,E,F,O]
这里备注一下新式类和旧式类的区别:
Python2.X中有新式类和旧式类之分:
在Python2.X中,新式类需要特别定义为如下形式:
class Tencent(object):
旧式类:
class Tencent()
#或者
class Tencednt: #两种定义方式均为旧式类。
而在Python3.X中,所有类无论以哪种方式定义,均为形式类。
class Tencent(): #新式类
class Tencent: #新式类
class Tencent(object): #还是新式类
在Python2.X中mro使用的算法是深度优先原则。
深度优先即从左往右依次先向上搜索,然后再按从左至右的顺序搜索。
在Python3.X中mro使用的算法是广度优先原则。
广度优先即先满足从左至右搜索的原则,然后在向上搜索。
以上就是相关解释,其中包含个人的想法,特此记录下来以免日后忘记,若有错误之处,望指正,感谢。
关于Python类的多继承中的__mro__属性使用的C3算法以及继承顺序解释的更多相关文章
- Python 类的多继承
#类的多继承 ''' 与c++不同,python的类经过优化,多继承时不会产生方法二义性 ''' #python中所有的类都是默认继承于object类 class A(object): def tes ...
- Python类(三)-多继承的区别
多继承的有两个方式,一个是广度优先,一个是深度优先Python2中经典类按深度优先,新式类按广度优先Python3中经典类和新式类都按广度优先 # -*- coding:utf-8 -*- __aut ...
- js继承中,原型属性的继承探究
最近研究了js的继承,看了幻天芒的文章http://www.cnblogs.com/humin/p/4556820.html#3947420,明白了最好是使用apply或call方法来实现继承. 已知 ...
- python全栈开发day103-python垃圾回收机制、mro和c3算法解析、跨域jsonp\CORS、Content-Type组件
Python垃圾回收 -- 引用计数 -- Python为每个对象维护一个引用计数 -- 当引用计数为0的 代表这个对象为垃圾 -- 标记清除 -- 解决孤立的循环引用 -- 标记根节点和可达对象 - ...
- python学习笔记013——模块中的私有属性
1 私有属性的使用方式 在python中,没有类似private之类的关键字来声明私有方法或属性.若要声明其私有属性,语法规则为: 属性前加双下划线,属性后不加(双)下划线,如将属性name私有化,则 ...
- python 列表字典按照字典中某个valu属性进行排序
对用户名进行排序 1. 直接上代码 base_dn_list = [ {', 'tenant': 'HAD', 'role': {'roleID': 'project', 'roleName': '项 ...
- 『无为则无心』Python面向对象 — 55、多层继承和继承中的私有成员
目录 1.Python支持多层继承 (1)多层继承实现 (2)多层继承和多重继承区别 2.继承中的私有成员 (1)继承中父类私有属性和私有方法 (2)获取和修改私有属性值 1.Python支持多层继承 ...
- 深入super,看Python如何解决钻石继承难题 【转】
原文地址 http://www.cnblogs.com/testview/p/4651198.html 1. Python的继承以及调用父类成员 python子类调用父类成员有2种方法,分别是普通 ...
- 深入super,看Python如何解决钻石继承难题
1. Python的继承以及调用父类成员 python子类调用父类成员有2种方法,分别是普通方法和super方法 假设Base是基类 class Base(object): def __init_ ...
随机推荐
- CodeForces - 922D Robot Vacuum Cleaner (贪心)
Pushok the dog has been chasing Imp for a few hours already. Fortunately, Imp knows that Pushok is a ...
- onCreate不加载布局
如果Activity重写的是 onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentS ...
- 21.python的模块(Module)和包(Package)
目录 模块(Module)和包(Package) 模块(modue)的概念 模块导入方法 1.import 语句 2.from-import 语句 3.from-import* 语句 4.运行本质 i ...
- flutter 安装环境 Mac
1.这是我第二次mac 安装 flutter环境了,但是这种东西记不住.打开写一下 有用的东西 一. ls vi 等命令 command not found原因是因为环境变量的问题,编辑profile ...
- Alibaba Cloud Toolkit 使用心得(IDEA版)
一.安装插件 确保 IntelliJ IDEA 在 2018.1 或更高版本 打开 Settings - Plugins 搜索安装 Alibaba Cloud Toolkit 二.配置环境 Deplo ...
- 0002 认识HTML(骨架、DOCTYPE、lang、charset)
学习目标 理解 1.HTML的概念 2.HTML标签的分类 3.HTML标签的关系 4.HTML标签的语义化 应用 1.HTML骨架格式 2.sublime基本使用 1. HTML 初识 HTML 指 ...
- HashMap 原理解析
HashMap是由数组加链表的结合体.如下图: 图中可以看出HashMap底层就是一个数组结构,每个数组中又存储着链表(链表的引用) JDK1.6实现hashmap的方式是采用位桶(数组)+链表的方式 ...
- zabbix监控mysql脚本(仅供参考)
mysql客户端添加 /etc/zabbix/zabbix_agentd.d.userparameter_mysql.conf UserParameter=mysql.version,mysql -V ...
- Python学习3月8号【python编程 从入门到实践】---》笔记(1)
第十章:处理文件和异常 #学习处理文件,让程序能够快速地分析大量的数据#学习错误处理,避免程序在面对意外情形时崩溃#学习异常,是python创建的特殊对象,用于管理程序运行时出现#学习模块json,它 ...
- HDU4734 F(x) 题解 数位DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4734 题目大意: 对于一个 \(n\) 位十进制数 \(x\) (\(A_nA_{n-1}A_{n-2 ...