```python • MRO(Method Resolution Order):方法解析顺序 • 对于支持继承的编程语言来说,其方法(属性)可能定义在当前类,也可能来自于基类,(二义性),所以在方法调用时就需要对当前类和基类进行搜索以确定方法所在的位置。而搜索的顺序就是所谓的“方法解析顺序(MRO)”。对于只支持单继承的语言来说,MRO一般比较简单,而对于Python这种支持多继承的语言来说,MRO就复杂很多。MRO其实就是把类的继承关系线性化的一个过程。 ``` • Python中三种不同的MRO ```python • 经典类从左到右的深度优先遍历(DFS) ``` ```python • Python 2.2版本:新式类(默认继承于Object)诞生,此时经典类和新式类共存,python2.2针对新式类提出了新的MRO计算方法,并在定义类时就计算出该类的MRO并将其作为类的属性,因此新式类可以直接通过__mro__属性获取类的MRO • 1. 经典类MRO采用DFS(深度优先搜索(子节点顺序:从左到右)) • 2. 新式类MRO采用BFS(广度优先搜索(子节点顺序:从左到右)) ``` ```python • Python 2.3-2.7版本:因为之前的BFS 存在较大的问题,所以从python2.3开始,新式类的MRO算法采用C3算法 • Python 3以后只存在新式类了,新式类的MRO依旧采用的是C3算法 ``` ```python • C3算法 • mro(A)=[A] • mro(A( B1 , B2 , ... Bn) )=[A] + merge( mro(B1) , mro(B2) , ... , mro(Bn) , [B1,B2,...,Bn] ) (列表相加还为列表) • 其中关键在于merge(),其输入是一组列表,按照如下方式输出一个列表(一个列表的表头指列表的第一个元素组成的列表,表尾指表头后面的元素组成的列表(可以为空),可以参照广义表的定义): • 1.检查第一个列表的头元素,记为H。 • 2.若H未出现在其他列表的尾部,则将其输出,并将其从所有列表中删除,然后回到步骤1;否则,取出下一个列表的头部记作H,继续该步骤。 • 重复上述步骤,直至列表为空或者不能再找出可以输出的元素,如果是前一种情况,则算法结束;如果是后一种情况,说明无法构建继承关系,python会抛出异常。 • C3算法有点类似于图的拓扑排序,但他同时还考虑了基类的出现顺序 • Python 3使用的C3算法并不是万能的,有些情况它也不能解决,会抛出异常,需要手工去解决 ``` ```python # 无法计算mro的例子,python会抛出异常 # class x: # pass # class y: # pass # class a(x,y): # pass # class b(y,x): # pass # class c(a,b): # pass # # print(c.__mro__) # 异常: # TypeError: Cannot create a consistent method resolution order (MRO) for bases x, y ``` • 可以计算mro的例子 ```python class A: pass class B(A): pass class C(A): pass class D(B, C): pass class E: pass class F(D, E): pass class G(F, D): pass class H: pass class C1(H, G): pass print(C1.__mro__) # [C1,H,G,F,D,B,C,A,E] # print(D.__mro__) # mro(C1(H,G)) # = [C1] + merge([H] , mro(G) , [H,G]) # = [C1] + merge([H] , [G,F,D,B,C,A,E] , [H,G]) # = [C1,H,G,F,D,B,C,A,E] # # mro(G(F,D)) # = [G] + merge(mro(F) , mro[D] , [F,D]) # = [G] + merge([F,D,B,C,A,E] , [D,B,C,A] , [F,D]) # = [G,F,D,B,C,A,E] # # mro(F(D,E)) # = [F] + merge(mro(D) , [E] , [D,E]) # = [F] + merge([D,B,C,A] , [E] , [D,E]) # = [F,D,B,C,A,E] # # mro(D(B,C)) # = [D] + merge(mro(B) , mro(C) , [B,C]) # = [D] + merge([B,A] , [C,A] , [B,C]) # = [D,B] + merge([A] , [C,A] , [C]) # = [D,B,C] + merge([A] , [A]) # = [D,B,C,A] # # mro(B(A)) # = [B] + merge(mro(A) , [A]) # mro(A)=[A] # =[B] + [A] # =[B,A] # # mro(C[A]) # = [C] + merge(mro(A) , [A]) # mro(A)=[A] # =[C] + [A] # =[C,A] ``` ```python class O: pass class D(O): pass class E(O): pass class F(O): pass class B(D, E): pass class C(E, F): pass class A(B, C): pass print(A.mro()) # [A,B,D,C,E,F,O] # 输出是一个列表 print(A.__mro__) # [A,B,D,C,E,F,O] # 输出是一个元组 # mro(A(B, C)) # =[A]+merge(mro(B),mro(C),[B,C]) # =[A]+merge([B,D,E,0],[C,E,F,0]+[B,C]) # =[A,B,D,C,E,F,0] # # mro(B(D,E)) # =[B]+merge(mro(D),mro(E),[D,E]) # =[B,D,E,0] # # mro(C(E,F)) # =[C]+merge(mro[E],mro(F),[E,F]) # =[C]+merge([E,0],[F,0],[E,F]) # =[C]+[E]+merge([0],[F,0],[F]) # =[C,E]+[F]+merge([0],[0]) # =[C,E,F,0] # # mro(D(0)) # =[D]+merge(mro(0),[0]) # =[D,0] # # mro(E(0)) # =[E]+merge(mro(0),[0]) # =[E,O] # # mro(F(0)) # =[F]+merge(mro(0),[0]) # =[F]+[0] # =[F,0] ``` 最后修改:2021 年 11 月 14 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 ¥¥阿巴阿巴¥¥
15 条评论
果博东方客服开户联系方式【182-8836-2750—】?薇- cxs20250806】
果博东方公司客服电话联系方式【182-8836-2750—】?薇- cxs20250806】
果博东方开户流程【182-8836-2750—】?薇- cxs20250806】
果博东方客服怎么联系【182-8836-2750—】?薇- cxs20250806】
作者的才华横溢,让这篇文章成为了一篇不可多得的艺术品。
若能在案例选择上更贴近现实,说服力会进一步提升。
《走向太阳》剧情片高清在线免费观看:https://www.jgz518.com/xingkong/71300.html
你的文章内容非常卖力,让人点赞。 http://www.55baobei.com/QPc0xqyOuX.html
《德云斗笑社》大陆综艺高清在线免费观看:https://www.jgz518.com/xingkong/55365.html
你的文章充满了智慧,让人敬佩。 http://www.55baobei.com/a3fXMn4Y6Q.html
《好莱坞百年百个明星》记录片高清在线免费观看:https://www.jgz518.com/xingkong/120844.html
你的文章内容非常卖力,让人点赞。 https://www.yonboz.com/video/17768.html
你的文章让我感受到了正能量,非常棒! http://www.55baobei.com/33zj88rwhC.html
《宠物联盟》国产动漫高清在线免费观看:https://www.jgz518.com/xingkong/50393.html
你的文章让我感受到了生活的美好,谢谢! https://www.yonboz.com/video/50893.html
看的我热血沸腾啊www.jiwenlaw.com
想想你的文章写的特别好https://www.237fa.com/
叼茂SEO.bfbikes.com