首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python MRO

Python MRO

作者头像
雪飞鸿
发布2020-06-22 14:47:30
6810
发布2020-06-22 14:47:30
举报
文章被收录于专栏:me的随笔me的随笔

文中代码基于Python3.7

对于Python中的多继承情况,运行时在搜索对象的属性或方法时,需要遵循一定的顺序规则,这个规则称为:Method Resolution Order (MRO).

MRO规则可以总结为以下三句话:

  • In the multiple inheritance scenario, any specified attribute is searched first in the current class. If not found, the search continues into parent classes in depth-first, left-right fashion without searching the same class twice.
  • So, first it goes to super class (and its super classes) given first in the list then second super class (and its super classes) , from left to right order. Then finally Object class, which is a super class for all classes. 这里的list指的是多个父类组成的list,如: class M(X,Y,Z): pass list就是(X,Y,Z)
  • When in MRO we have a super class before subclass then it must be removed from that position in MRO. 这一句和第一句对应起来看,一个类只被检索一次,所以基类要往后移

可以调用类型对象的mro方法或者__mro__属性来获取类型的MRO信息。

class X:
    def hello(self):
        print('x')
​
​
class Y:
    def hello(self):
        print('y')
    
    def world(self):
        print('y_world')
​
​
class Z:
    def hello(self):
        print('z')
​
​
class A(X):
    def hello(self):
        print('a')
​
​
class B(Y,Z):
    def hello(self):
        print('b')
​
​
class M(B, A): 
    pass
​
print(M.mro())
print(M.__mro__)
​
# 输出:
# list类型
[<class '__main__.M'>, <class '__main__.B'>, <class '__main__.Y'>, <class '__main__.Z'>, <class '__main__.A'>, <class '__main__.X'>, <class 'object'>]
# tuple类型
(<class '__main__.M'>, <class '__main__.B'>, <class '__main__.Y'>, <class '__main__.Z'>, <class '__main__.A'>, <class '__main__.X'>, <class 'object'>)

MRO图示如下:

goes to super class (and its super classes) given first in the list then second super class (and its super classes) , from left to right order. Then finally Object class

depth-first, left-right fashion without searching the same class twice ,得到MRO列表:[<class '__main__.M'>, <class '__main__.B'>, <class '__main__.Y'>, <class '__main__.Z'>, <class '__main__.A'>, <class '__main__.X'>, <class 'object'>]


B和A均继承自Z,M继承自B和A:

class X:
    def hello(self):
        print('x')
​
​
class Y:
    def hello(self):
        print('y')
    
    def world(self):
        print('y_world')
​
​
class Z:
    def hello(self):
        print('z')
​
​
class A(X,Z):
    def hello(self):
        print('a')
​
​
class B(Y,Z):
    def hello(self):
        print('b')
​
​
class M(B, A): 
    pass
​
print(M.mro())
​
# 输出:
# [<class '__main__.M'>, <class '__main__.B'>, <class '__main__.Y'>, <class '__main__.A'>, <class '__main__.X'>, <class '__main__.Z'>, <class 'object'>]

MRO图示如下:

goes to super class (and its super classes) given first in the list then second super class (and its super classes) , from left to right order. Then finally Object class

depth-first, left-right fashion without searching the same class twice ,得到MRO列表:[<class '__main__.M'>, <class '__main__.B'>, <class '__main__.Y'>, <class '__main__.A'>, <class '__main__.X'>, <class '__main__.Z'>, <class 'object'>]


class X:
    def hello(self):
        print('x')
​
​
class Y:
    def hello(self):
        print('y')
    
    def world(self):
        print('y_world')
​
​
class Z:
    def hello(self):
        print('z')
​
​
class A(X,Z):
    def hello(self):
        print('a')
​
​
class B(Y,Z):
    def hello(self):
        print('b')
​
​
class M(B, A, Y): 
    pass
​
print(M.mro())
​
# 输出
# [<class '__main__.M'>, <class '__main__.B'>, <class '__main__.A'>, <class '__main__.Y'>, <class '__main__.X'>, <class '__main__.Z'>, <class 'object'>]

MRO图示如下:

goes to super class (and its super classes) given first in the list then second super class (and its super classes) , from left to right order. Then finally Object class

这个MRO图可以继续简化:

depth-first, left-right fashion without searching the same class twice

得到MRO列表为[<class '__main__.M'>, <class '__main__.B'>, <class '__main__.A'>, <class '__main__.Y'>, <class '__main__.X'>, <class '__main__.Z'>, <class 'object'>]


When in MRO we have a super class before subclass then it must be removed from that position in MRO

下面是一个会报错的示例:

class A:
    def process(self):
        print('A process()')
​
​
class B(A):
    def process(self):
        print('B process()')
​
​
class M(A, B):
    pass
​
print(M.mro())
​
# 输出:
# TypeError: Cannot create a consistent method resolution
# order (MRO) for bases A, B

MRO图示:

如果一个方法或属性同时存在与B和A,应为M直接继承B又直接继承A,那么通过M来调用时就不知道是该从B中还是A中获取这个方法或属性了,干脆就报错吧。我觉得MRO顺序应该为:M->B->A->object。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-06-19 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档