python 多继承 MRO
MRO 多继承
MRO, Method Resolution Order
class A:def say(self):print("A")class M(A):passm = M()
m.say()
输出为:A
class A:def say(self):print("A")class B:def say(self):print("B")class M(B):passm = M()
m.say()
输出为:B
class A:def say(self):print("A")class B:def say(self):print("B")class M(A, B):passm = M()
m.say()
输出为:A
class A:def say(self):print("A")class B:def say(self):print("B")class C(A):passclass M(C, B):passm = M()
m.say()
输出为:A
class A:def say(self):print("A")class B(A):def say(self):print("B")class C(A):passclass M(C, B):passm = M()
m.say()
输出为:B
怎么从父类里找某个类的优先函数?这就是MRO
两种方式:
M.mro()
M.__mro__
上面最后一个例子打印出来像这样:
[__main__.M, __main__.C, __main__.B, __main__.A, object]
可以看出,在调用M的say()方法时,先在M中找没找到,又在C中找,没找到,最后在B中找,找到了,用的就是B中的say()方法,优先级越来越低
算法
python从2.3版本用的就是C3 MRO(wiki | paper)
C3算法的三个C:(阅读顺序:2->3->1,标号只为了与维基百科一致)
a consistent extended precedence graph:把每对类都画上箭头,箭头方向取决于“在这对类的最小公共子类上,这两个类或它们的子类的优先级顺序”(比较难理解,看下面这幅图的解释)
precedence graph类似于下图,指子类和父类之间的关系
解释:观察
scrolling-mixin
和editing-mixin
两个类,第二个C决定了所有scrollable-pane
及其子类中,pane
都优先于scrolling-mixin
,同理所有editable-pane
及其子类中,pane
都优先于editing-mixin
。第三个C保证了在editable-scrollable-pane
中,使用的方法一定是scrollable-pane
或editable-pane
中使用的方法。第一个C确定了scrolling-mixin
和editing-mixin
的顺序:- 找到两者的最小公共子类,即保证这个子类的所有父类都不是两者共同的子类,这个例子中就是
editable-scrollable-pane
- 只要
scrolling-mixin
或scrolling-mixin
的子类排在editing-mixin
或editing-mixin
的子类之前,则scrolling-mixin
优先级就高于editing-mixin
,这个例子中,由于scrollable-pane
排在editable-pane
之前,所以scrolling-mixin
优先级高于editing-mixin
- 找到两者的最小公共子类,即保证这个子类的所有父类都不是两者共同的子类,这个例子中就是
preservation of local precedence order(局部的优先顺序):当一个class继承了多个class时,会优先使用写在前面的class中的方法;同时,这个class的所有subclass(子类)也同样保持这个特性。比如M继承了(A,B)(注意顺序),C继承了M,对C调用say()方法的时候A的优先级也比B高
比如:
class A:def say(self):print("A")class B:def say(self):print("B")class M(A, B):passm = M() m.say()
输出A,然而:
class A:def say(self):print("A")class B:def say(self):print("B")class M(B, A):passm = M() m.say()
输出B
fitting a monotonicity criterion(符合单调性标准):任何一个class使用的方法必须来自其直接父类使用的方法,这一部分比较复杂,大家可以去b站看码农高天的视频,很清晰的。这是论文中提到的一个例子
假设有一个方法只存在于day-boat和wheel-boat上,可以看到,pedalo的两个父类:pedal-wheel-boat和small-catamaran在继承时优先使用day-boat的方法(由它们的MRO得来),而pedalo作为它们的子类,优先使用的是wheel-boat的方法,它没有使用父类使用的方法,或者说它跳过了父类,使用了其他类的方法,这就破坏了单调性标准
不满足3C算法的类定义
class A:def say(self):print("A")class B:def say(self):print("B")# 由第二个C知道,对class C来说,A在B前面
class C(A, B):pass# 由第二个C知道,对class D来说,B在A前面
class D(B, A):pass# 由第一个C知道,由于C排在D之前,那说明A应该排在B之前
# 但class D规定B排在A前面,产生矛盾
class M(C, D):pass
继承关系如下图所示:
结语
多继承在python中是被允许的语法,在java中则取消了多继承。MRO最基本需要掌握在写完代码之后怎么通过mro()方法或__mro__
成员判断调用方法时候的优先级。文中提到的up主码农高天在讲解python一些比较细致和深入的问题上很清晰,感兴趣的小伙伴可以关注关注。如果有任何疑问或错误欢迎在评论区里提出,我们一起讨论~
python 多继承 MRO相关推荐
- Python多继承mro示例
Python多继承mro示例 以下是python方法解析顺序的示例,详细的解释见代码的注释部分. # 1 解释python mro的执行顺序,详见数字序号的顺序 class Base(object): ...
- Python多继承mro
在python语言里是支持继承这一概念的,也就是一个class可以继承一些其他class方法或者数据,在继承的时候有的比较简单,比如下面这段代码就是classM继承了classA class A(): ...
- python 多继承与super使用详解_继承中的MRO与super详解
Python进阶-继承中的MRO与super 写在前面如非特别说明,下文均基于Python3 摘要 本文讲述Python继承关系中如何通过super()调用"父类"方法,super ...
- Python - 多继承与MRO
(一)多继承 网上关于多继承.MRO和C3算法的讲解比较多,在此不再赘述. 我们可以利用类的__mro__ 属性或者 mro() 方法查看某个类的MRO列表(方法调用顺序). (二)经典案例 当执 ...
- python中的MRO与多继承
相关概念: MRO:Method Resolution Order,即方法解析顺序,是python中用于处理二义性问题的算法 二义性: python支持多继承,多继承的语言往往会遇到以下两类二义性的问 ...
- python基础 继承
继承 继承指的是类与类之间的关系,是一种什么"是"什么的关系,继承的功能之一就是用来解决代码重用问题 继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父 ...
- python面向对象继承_Python 面向对象 --- 继承
目标 单继承 多继承 面向对象三大特性 1,封装 根据 职责 将 属性 和 方法 封装 到以抽象的 类 中 2,继承 实现代码的重用,相同的代码不需要重复的缩写 3,多态 不同的对象调用相同的方法,产 ...
- Python的继承多态
Python的继承多态 文章目录 Python的继承多态 一.私有属性和私有方法 01. 应用场景及定义方式 02. 伪私有属性和私有方法 二.单例 01. 单例设计模式 单例设计模式的应用场景 02 ...
- python多继承顺序及分配,python多继承的查找顺序是什么?
1.查找顺序 (1)本地优先,自己定义或重写的方法优先.本地没有的,按照继承列表,从左往右查找: (2)单调性,所有子类,也要满足查找顺序.也就是说 A 继承 B C,A 会先找 B 再找 C.但是在 ...
- Python 多继承
1.多继承 概念 子类 可以拥有 多个父类,并且具有 所有父类的 属性 和 方法: 例如:孩子 会继承自己 父亲 和 母亲 的 特性: 语法 class 子类(父类1,父类2...)pass clas ...
最新文章
- C 语言编程 — const 关键字
- python一键安装包_Python一键安装全部依赖包
- [数据结构] - 串
- IntelliJ IDEA创建web项目及异常问题解决
- ansible基础配置
- 数据库设计笔记——概述(一)
- C#怎么用代码模拟手机去访问手机网站抓取数据
- 软件工程专业学python_笨办法学Python(0)
- android系统b181更新包,华为nova 2s官方固件rom刷机包_华为nova2s完整系统升级包
- 程序员必备的10个B站优质UP主!
- 体细胞选择区分癌基因和抑癌基因
- 使用Python构造数据包
- 中国大学MOOC-陈越、何钦铭-数据结构-起步能力自测题
- 软件架构与设计(二)-----架构模型
- mysql的版本是什么_mysql版本号是什么意思?
- pytorch 指定卡1_如何为TensorFlow和PyTorch自动选择空闲GPU,解决抢卡争端
- 面试-JVM-类加载-类加载器--自定义类加载器-JVM调优
- 打开Flutter动画的另一种姿势——Flare,android面试题选择题
- 2021-11-06 工作记录--LayUI-敲击键盘enter键,仍可以实现搜索
- vector 排序方法sort的使用
热门文章
- Python与SEO,搜狗站长平台链接提交工具Python脚本源码
- Result Maps collection does not contain value for错误提示
- DAC904硬件电路
- 【导数术】10.导数数列不等式
- 关于延拓定理的一点注解
- c51中的_crol_和_cror_
- 一位仁兄对于项目管理的精辟见解
- ubuntu 18.04设置静态ip(固定IP地址)
- linux+gps测试流程图,卫星导航产品(GPS)测试方案详解
- 给初学者:用VB写外挂 ———— 如何给外挂定义一组热键:红色警戒五项属性修改器VB版