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

两种方式:

  1. M.mro()
  2. 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,标号只为了与维基百科一致)

  1. a consistent extended precedence graph:把每对类都画上箭头,箭头方向取决于“在这对类的最小公共子类上,这两个类或它们的子类的优先级顺序”(比较难理解,看下面这幅图的解释)

    precedence graph类似于下图,指子类和父类之间的关系

    解释:观察scrolling-mixinediting-mixin两个类,第二个C决定了所有scrollable-pane及其子类中,pane都优先于scrolling-mixin,同理所有editable-pane及其子类中,pane都优先于editing-mixin。第三个C保证了在editable-scrollable-pane中,使用的方法一定scrollable-paneeditable-pane中使用的方法。第一个C确定了scrolling-mixinediting-mixin的顺序:

    • 找到两者的最小公共子类,即保证这个子类的所有父类都不是两者共同的子类,这个例子中就是editable-scrollable-pane
    • 只要scrolling-mixinscrolling-mixin的子类排在editing-mixinediting-mixin的子类之前,则scrolling-mixin优先级就高于editing-mixin,这个例子中,由于scrollable-pane排在editable-pane之前,所以scrolling-mixin优先级高于editing-mixin
  2. 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

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

  1. Python多继承mro示例

    Python多继承mro示例 以下是python方法解析顺序的示例,详细的解释见代码的注释部分. # 1 解释python mro的执行顺序,详见数字序号的顺序 class Base(object): ...

  2. Python多继承mro

    在python语言里是支持继承这一概念的,也就是一个class可以继承一些其他class方法或者数据,在继承的时候有的比较简单,比如下面这段代码就是classM继承了classA class A(): ...

  3. python 多继承与super使用详解_继承中的MRO与super详解

    Python进阶-继承中的MRO与super 写在前面如非特别说明,下文均基于Python3 摘要 本文讲述Python继承关系中如何通过super()调用"父类"方法,super ...

  4. Python - 多继承与MRO

    (一)多继承 网上关于多继承.MRO和C3算法的讲解比较多,在此不再赘述. 我们可以利用类的__mro__ 属性或者 mro() 方法查看某个类的MRO列表(方法调用顺序).   (二)经典案例 当执 ...

  5. python中的MRO与多继承

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

  6. python基础 继承

    继承 继承指的是类与类之间的关系,是一种什么"是"什么的关系,继承的功能之一就是用来解决代码重用问题 继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父 ...

  7. python面向对象继承_Python 面向对象 --- 继承

    目标 单继承 多继承 面向对象三大特性 1,封装 根据 职责 将 属性 和 方法 封装 到以抽象的 类 中 2,继承 实现代码的重用,相同的代码不需要重复的缩写 3,多态 不同的对象调用相同的方法,产 ...

  8. Python的继承多态

    Python的继承多态 文章目录 Python的继承多态 一.私有属性和私有方法 01. 应用场景及定义方式 02. 伪私有属性和私有方法 二.单例 01. 单例设计模式 单例设计模式的应用场景 02 ...

  9. python多继承顺序及分配,python多继承的查找顺序是什么?

    1.查找顺序 (1)本地优先,自己定义或重写的方法优先.本地没有的,按照继承列表,从左往右查找: (2)单调性,所有子类,也要满足查找顺序.也就是说 A 继承 B C,A 会先找 B 再找 C.但是在 ...

  10. Python 多继承

    1.多继承 概念 子类 可以拥有 多个父类,并且具有 所有父类的 属性 和 方法: 例如:孩子 会继承自己 父亲 和 母亲 的 特性: 语法 class 子类(父类1,父类2...)pass clas ...

最新文章

  1. C 语言编程 — const 关键字
  2. python一键安装包_Python一键安装全部依赖包
  3. [数据结构] - 串
  4. IntelliJ IDEA创建web项目及异常问题解决
  5. ansible基础配置
  6. 数据库设计笔记——概述(一)
  7. C#怎么用代码模拟手机去访问手机网站抓取数据
  8. 软件工程专业学python_笨办法学Python(0)
  9. android系统b181更新包,华为nova 2s官方固件rom刷机包_华为nova2s完整系统升级包
  10. 程序员必备的10个B站优质UP主!
  11. 体细胞选择区分癌基因和抑癌基因
  12. 使用Python构造数据包
  13. 中国大学MOOC-陈越、何钦铭-数据结构-起步能力自测题
  14. 软件架构与设计(二)-----架构模型
  15. mysql的版本是什么_mysql版本号是什么意思?
  16. pytorch 指定卡1_如何为TensorFlow和PyTorch自动选择空闲GPU,解决抢卡争端
  17. 面试-JVM-类加载-类加载器--自定义类加载器-JVM调优
  18. 打开Flutter动画的另一种姿势——Flare,android面试题选择题
  19. 2021-11-06 工作记录--LayUI-敲击键盘enter键,仍可以实现搜索
  20. vector 排序方法sort的使用

热门文章

  1. Python与SEO,搜狗站长平台链接提交工具Python脚本源码
  2. Result Maps collection does not contain value for错误提示
  3. DAC904硬件电路
  4. 【导数术】10.导数数列不等式
  5. 关于延拓定理的一点注解
  6. c51中的_crol_和_cror_
  7. 一位仁兄对于项目管理的精辟见解
  8. ubuntu 18.04设置静态ip(固定IP地址)
  9. linux+gps测试流程图,卫星导航产品(GPS)测试方案详解
  10. 给初学者:用VB写外挂 ———— 如何给外挂定义一组热键:红色警戒五项属性修改器VB版