python的mro算法什么用?一文带你深入了解mro
Admin 2021-09-15 群英技术资讯 947 次浏览
这篇文章主要给大家分享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->object
A->Y->X->object
C->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进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
在很多企业会使用闲置的 Windows 机器作为临时服务器,有时候我们想远程调用里面的程序或查看日志文件。本文分享了利用Python远程控制Windows服务器的方法,感兴趣的可以学习一下
Python内置函数-sorted()函数。sorted() 函数对所有可迭代的对象进行排序操作。
不管你是做数据分析,还是网络爬虫,Web 开发、亦或是机器学习,你都离不开要和数据库打交道,而 MySQL 又是最流行的一种数据库,这篇文
turtle库是python的基础绘图库,经常被用来给孩子们介绍编程知识的方法库,是标准库之一,利用turtle可以制作很多复杂的绘图。本文将为大家介绍通过turtle库绘制的一些有趣的图画,感兴趣的小伙伴可以学习一下
这篇文章主要介绍了Python中模块(Module)和包(Package)的区别详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008