mro()"的作用是什么?

185 投票
5 回答
98728 浏览
提问于 2025-04-15 17:41

mro() 是干什么的?


下面是来自 django.utils.functional 的一个例子:

for t in type(res).mro():  # <----- this
    if t in self.__dispatch:
        return self.__dispatch[t][funcname](res, *args, **kw)

5 个回答

20

这可能会显示解析的顺序。

class A(object):
    def dothis(self):
        print('I am from A class')

class B(A):
    pass

class C(object):
    def dothis(self):
        print('I am from C class')

class D(B, C):
    pass

d_instance = D()
d_instance.dothis()
print(D.mro())

输出结果是:

I am from A class
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.A'>, <class '__main__.C'>, <class 'object'>]

这个规则是深度优先的,这里意味着顺序是 DBAC

在查找继承类时,Python 通常使用深度优先的顺序,但当两个类都继承自同一个类时,Python 会从方法解析顺序(MRO)中去掉该类的第一次出现。

103

mro()方法解析顺序 的缩写。它会返回一个列表,里面列出了这个类所继承的所有类型,并按照查找方法的顺序排列。

mro()__mro__ 只适用于新式类。在 Python 3 中,它们可以正常使用。而在 Python 2 中,这些类需要从 object 继承才能使用。

273

跟着我一起看...:

>>> class A(object): pass
... 
>>> A.__mro__
(<class '__main__.A'>, <type 'object'>)
>>> class B(A): pass
... 
>>> B.__mro__
(<class '__main__.B'>, <class '__main__.A'>, <type 'object'>)
>>> class C(A): pass
... 
>>> C.__mro__
(<class '__main__.C'>, <class '__main__.A'>, <type 'object'>)
>>> 

如果我们只有单一继承,__mro__ 就是一个元组,里面包含了:这个类、它的父类、它的父类的父类,依此类推,一直到 object(当然,这只适用于新式类)。

现在,谈谈 多重 继承...:

>>> class D(B, C): pass
... 
>>> D.__mro__
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>)

...在 __mro__ 中,你可以放心,没有任何类会重复出现,也不会有类出现在它的祖先之后。只有那些在同一层次上首次出现的类(比如这个例子中的 B 和 C)会按照从左到右的顺序出现在 __mro__ 中。

你在类的实例上获取的每一个属性,不仅仅是方法,都是沿着 __mro__ 查找的。所以,如果在祖先类中有多个类定义了同一个名字,这就告诉你这个属性会在哪里找到——在 __mro__ 中第一个定义这个名字的类里。

撰写回答