这篇文章主要给大家分享python的mro算法的内容,可能一些朋友对mro不是很了解,但是没关系,下文有详细的介绍,及实例代码供大家参考,对python的mro算法感兴趣的朋友接下来就跟随小编一起来学习一下吧。
__mro__可以查看方法搜索顺序实际代码
class A:
def test(self):
print("AAA-test")
class B:
def test(self):
print("BBB-test")
# 继承了三个类,B、A、还有默认继承的 object
class C(B, A):
...
# 通过类对象调用,不是实例对象!
print(C.__mro__)
# 输出结果
(<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
__mro__的输出结果从左往右的顺序查找的类图

其实 MRO 是涉及一个底层算法的,下面来详细讲解一下
Python 发展到现在经历了三种算法
需要在 python2 环境下运行这段代码
实际代码
# 旧式类算法
class A:
def test(self):
print("CommonA")
class B(A):
pass
class C(A):
def test(self):
print("CommonC")
class D(B, C):
pass
D().test()
# python2 下的运行结果
CommonA

类图

分析
D->B->A->C->A以上面的代码栗子来讲
D->B->A->C->A D->B->C->A虽然解决了旧式 MRO 算法的问题,但可能会违反单调性原则
在子类存在多继承时,子类不能改变父类的 MRO 搜索顺序,否则会导致程序发生异常
实际代码
class X(object):
pass
class Y(object):
pass
class A(X, Y):
pass
class B(Y, X):
pass
class C(A, B):
pass
深度优先遍历后的搜索顺序为:C->A->X->object->Y->object->B->Y->object->X->object
相同取后者的搜索顺序为:C->A->B->Y->X->object
分析不同类的 MRO
A->X->Y->objectA->Y->X->objectC->A->B->X->Y->object很明显,B、C 中间的 X、Y 顺序是相反的,就是说 B 被继承时,它的搜索顺序会被改变,违反了单调性
在 python2 中运行这段代码的报错

在 python3 中运行这段代码的报错

将上面第一个栗子的代码放到 python3 中运行
class A:
def test(self):
print("CommonA")
class B(A):
pass
class C(A):
def test(self):
print("CommonC")
class D(B, C):
pass
D().test()
# 输出结果
CommonC
以上面代码为栗子,C3 会把各个类的 MRO 等价为以下等式
了解一下:头、尾
以 A 类为栗,merge() 包含的 A 成为 L[A] 的头,剩余元素(这里只有 object)称为尾
重复以上步骤直到列表为空,则算法结束;如果不能再找出可以输出的元素,则抛出异常
class B(object): pass print(B.__mro__) (<class '__main__.B'>, <class 'object'>)
L[B] = L[B(object)]
= B + merge(L[object])
= B + L[object]
= B object
# 计算 MRO class B(object): pass class C(B): pass print(C.__mro__) (<class '__main__.C'>, <class '__main__.B'>, <class 'object'>)
L[C] = C + merge(L[B])
= C + L[B]
= C B object
O = object class F(O): pass class E(O): pass class D(O): pass class C(D, F): pass class B(D, E): pass class A(B, C): pass print(C.__mro__) print(B.__mro__) print(A.__mro__)
# 输出结果
(<class '__main__.C'>, <class '__main__.D'>, <class '__main__.F'>, <class 'object'>)
(<class '__main__.B'>, <class '__main__.D'>, <class '__main__.E'>, <class 'object'>)
(<class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.D'>, <class '__main__.E'>, <class '__main__.F'>, <class 'object'>)
L[O] = O = object
L[D] = D + merge(L[O])
= D O
L[C] = L[C(D, F)]
= C + merge(L[D], L[F], DF)
# 从前面可知 L[D] 和 L[F] 的结果
= C + merge(DO, FO, DF)
# 因为 D 是顺序第一个并且在几个包含 D 的 list 中是 head,
# 所以这一次取 D 同时从列表中删除 D
= C + D + merge(O, FO, F)
# 因为 O 虽然是顺序第一个但在其他 list (FO)中是在尾部, 跳过
# 改为检查第二个list FO
# F 是第二个 list 和其他 list 的 head
# 取 F 同时从列表中删除 F
= C + D + F + merge(O)
= C D F O
L[B] = L[B(D, E)]
= B + merge(L[D], L[E], DE)
= B + merge(DO, EO, DE)
= B + D + merge(O, EO, E)
= B + D + E + merge(O)
= B D E O
L[A] = L[A(B,C)]
= A + merge(L[B], L[C], BC)
= A + merge( BDEO, CDFO, BC )
= A + B + merge( DEO, CDFO, C )
# D 在其他列表 CDFO 不是 head,所以跳过到下一个列表的 头元素 C
= A + B + C + merge( DEO, DFO )
= A + B + C + D + merge( EO, FO )
= A + B + C + D + E + merge( O, FO )
= A + B + C + D + E + F + merge( O )
= A B C D E F O
O = object class F(O): pass class E(O): pass class D(O): pass class C(D, F): pass class B(E, D): pass class A(B, C): pass print(C.__mro__) print(B.__mro__) print(A.__mro__)
# 输出结果
(<class '__main__.C'>, <class '__main__.D'>, <class '__main__.F'>, <class 'object'>)
(<class '__main__.B'>, <class '__main__.E'>, <class '__main__.D'>, <class 'object'>)
(<class '__main__.A'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.D'>, <class '__main__.F'>, <class 'object'>)
L[O] = O = object
L[D] = D + merge(L[O])
= D O
L[C] = L[C(D, F)]
= C + merge(L[D], L[F], DF)
= C + merge(DO, FO, DF)
= C + D + merge(O, FO, F)
= C + D + F + merge(O)
= C D F O
L[B] = L[B(E, D)]
= B + merge(L[E], L[D], ED)
= B + merge(EO, DO, ED)
= B + E + merge(O, DO, D)
= B + E + D + merge(O)
= B E D O
L[A] = L[A(B, C)]
= A + merge(L[B], L[C], BC)
= A + merge(BEDO, CDFO, BC)
= A + B + merge(EDO, CDFO, C)
= A + B + E + merge(DO,CDFO, C)
= A + B + E + C + merge(O,DFO)
= A + B + E + C + D + merge(O, FO)
= A + B + E + C + D + F + merge(O)
= A B E C D F O
关于python的mro算法的内容就介绍到这,上述示例对帮助大家学习和理解mro算法有一定的帮助,有需要的朋友可以了解一下,如果还想要了解更多mro算法的内容,大家可以继续浏览群英网络其他相关的文章。
文本转载自脚本之家
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
长按识别二维码并关注微信
更方便到期提醒、手机管理