Python的MRO

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

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:
    pass

class E:
    pass

class D:
    pass

class B(D,E):
    pass

class C(D,F):
    pass

class 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).方法

 

转载请标明出处,原文地址:https://blog.csdn.net/come_from_pluto

深入解析 Python 中的 mro() 方法 MRO(方法解析顺序)是 Python多重继承中确定方法调用顺序的算法。当一个对象调用方法时,Python 将根据 MRO 查找类的方法。这种机制确保了所有父类的方法都能被正确调用,避免了潜在的冲突和混淆。MROPython 多重继承中非常重要的一个概念,它确保了在调用方法时能够按照正确的顺序进行解析。使用 ​​mro()​​ 方法和 ​​__mro__​​ 属性,开发者可以轻松地查看类的 MRO,帮助理解方法调用的顺序。​​super()​。 阅读详情

相关推荐

PythonMRO三定律”——关于Python中多继承C3-MRO算法的剖析

本文将带你由浅至深,逐步理解Python中的多继承C3-MRO算法。 本文从基础的MRO认识出发,简单了解C3-MRO的历史后展开C3-MRO算法的详细内容。接着通过“MRO三定律”的特殊角度深度解析C3-MRO算法的核心思想以及算法原理。

W-H2099的博客 1178

python-知识点(一)

python知识汇总

qq_17200461的博客 2208

python中的MRO

一:什么是MRO 所谓的MRO,就是方法解析顺序(Method Resolution Order)。在调用方法时,会对当前类以及所有的基类进行一个搜索,确定要调用的方法具体在哪。不管用哪种方式去确定MRO列表,必须满足 本地优先级和单调性。 本地优先级:指声明时父类的顺序,比如C(A,B),如果访问C类对象属性时,应该根据声明顺序,优先查找A类,然后再查找B类 单调性:如果在C的解析顺序中,A排在B的前面,那么在C的所有子类里,也必须满足这个顺序 二:常见的mro算法 1:mro=深度优先遍历的(

zhangdell的专栏 8565

Python】super() 函数丨MRO丨钻石继承

继承,super()函数,MRO

Shi_Xueqing的博客 1717

python中的类、继承mro列表

python中的类是面向对象语言的特征,类可以表示现实生活中的一大类,例如车,利用类生成实例可以 表示各种品牌、型号、年份不同的车。上述程序中self和my_new_car都是指向实例本身的引用。只是self用于Car类内部,my_new_car用于Car类外部。

qq_44327024的博客 349

Python3中类的多继承MRO顺序

python是一种面向对象的编程语言,其中重要编程方式之一是。通过继承,子类便可以扩展父类的功能,实现多态。继承有两种形式,一种是单继承,即一个类只继承一个父类;另一种是当然,子类所继承的所有父类同样也能有自己的父类,同样也可以实现多继承!fill:#333;color:#333;color:#333;fill:none;

qq_38380338的博客 1826

python中的super函数及MRO

super() 函数是用于调用父类(超类)的一个方法。 super是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO)、重复调用(钻石继承)等种种问题。 MRO就是类的方法解析顺序表, 其实也就是继承父类方法时的顺序表。 调用父类(超类)方法的两种方式:...

面向学姐编程 6519

PythonMRO

PythonMRO(方法解析顺序)采用 C3 算法解决多重继承中的方法调用顺序问题。MRO 遵循子类优先、继承顺序从左到右和单调性规则,可通过__mro__属性查看继承顺序。C3 算法通过递归合并父类 MRO 并检查一致性来确定调用顺序,复杂继承结构可能导致冲突(如菱形继承)。super()函数依据 MRO 动态调用父类方法。建议合理使用多继承,避免结构过于复杂,优先考虑 Mixin 模式。

qq_33764107的博客 768

python MRO

Python3采用C3线性化算法来生成MRO。保证子类优先于父类,多个父类按继承顺序依次查找,且每个类只出现一次,保持继承关系一致性。这样可以避免菱形继承等复杂多重继承结构下的二义性。passprint(admin.var) # 输出:user(先查User,再查Base)passpassprint(admin.var) # 输出:base(User没有,查Base)passpasspassMRO查找算法决定了多重继承下属性和方法的查找顺序。Python3采用C3线性化算法。

qq_37805832的博客 650

Python 多重继承 MRO 机制

MRO 是指在一个多重继承的类层次结构中,Python解释器查找方法或者属性的顺序。简单来说,当调用一个方法或一个属性时,Python会按照 MRO 定义的顺序逐层搜索,直到找到方法或属性,或是遍历完成所有父类。广度优先:优先访问类的直接父类从左到右:在多重继承类中,优先访问继承列表左边的父类。继承链唯一:每个父类在 MRO 中只出现一次,确保顺序一致性。MROPython 中解决 多重继承问题的关键机制,定义了多重继承时方法和属性的查找顺序。

wangqiang996的博客 1277

重学pythonmro

python继承是可以继承父类的属性和函数的,而python支持多继承,假设类C继承于类A和类B,那么,类C是否同时包含了A和B的初始化函数__init__?, 类C是否既可以按照类A的构造方法初始化,也可以按照类B的构造函数初始化?C3 算法的核心是为每个类生成一个线性化列表(linearization),这个列表是类本身、父类的线性化列表及父类声明顺序的 “合并结果”,需。当一个类继承自多个父类时,Python 需要确定:当调用一个方法或访问一个属性时,应该按照什么顺序去父类中查找。

cosseen的专栏 1316

mro python_python中的MRO算法[转]

为解决 Python 2.2 中 MRO 所存在的问题,Python 2.3以后采用了 C3 方法来确定方法解析顺序。你如果在 Python 2.3 以后版本里输入上述代码,就会产生一个异常,禁止创建具有二义性的继承关系:>>> class C(A, B): passTraceback (most recent call last):File "", line 1, in cla...

weixin_39882623的博客 186

python中的mro

发现一个号网站:http://stackoverflow.com 现在才发现,土呀: 什么是MRO Follow along...: >>> class A(object): pass ... >>> A.__mro__ (, ) >>> class B(A): pass ... >>> B.__mro__ (, , ) >>> class C(A): pass ... >>

qugang1982的专栏 729

python mro

什么是mro继承情况下,一个class如何从它的父类中找应该优先使用那个父类的函数,这个顺序就叫mro mro介绍 mro时每一个类会把它所有的父类和自己做一个线性化,也就是把它继承的类和它自己做一个排队,排队是保证自己是最高优先级,当调用方法或寻找数据的时候,会按照这个队列的优先级顺序从前往后找。 mro继承展示方式 寻找类的继承顺序有两种继承方式 1.类.mro 2.类.mro() 介绍 当建立一个新的类,并继承了其它类的时候,他首先会根据这个继承关系计算出mro ,当尝试调用方法或使用这个类的数

mzl9692的博客 435

Python3中MRO的含义及MRO算法的继承顺序

MRO(Method Resolution Order):方法解析顺序。 Python语言包含了很多优秀的特性,其中多重继承就是其中之一,但是多重继承会引发很多问题,比如二义性,Python中一切皆引用,这使得他不会像C++一样使用虚基类处理基类对象重复的问题,但是如果父类存在同名函数的时候还是会产生二义性,Python中处理这种问题的方法就是MRO。 如何查看一个类中的方法继承顺序,可以直接打印...

Python美丽星球--微信(Felixzfb) 1977

PythonMRO

1. MRO(Method Resolution Order) MRO即Method Resolution Order(方法解析顺序),即在调用方法时,会对当前类以及所有的基类进行一个搜索, 以确定该方法之所在,而这个搜索的顺序就是MRO。 一个类的 MRO 列表就是合并所有父类的 MRO 列表,并遵循以下三条原则: 1. 子类永远在父类前面 2. 如果有多个父类,会根据它们在列表中的顺序被检查 3. 如果对下一个类存在两个合法的选择,选择第一个父类 遇到多继承则按代码中继承列表的顺序从左往右写。若有类

wguo-up-site 1902

12 Python MRO

深究Python中类的MRO由来,发展以及计算方法解析顺序表

忧桑的小兔子 4247

mro python_python MRO

python MRO一个小题目你可以计算一个这样的题目,来验证你是否掌握了MRO,如果答案对的话,我想你可以不用看这个文章了""" Created by FizLin on 2017/08/03/-下午6:58mail: https://github.com/Fiz1994新式类的继承"""class Init(object):def __init__(self, value):print('In...

weixin_39890543的博客 384
上一篇: Python中的可变数据类型和不可变数据类型
下一篇: 关于像素间的一些基本关系(邻接、连通等)
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值