“ mro ()”是做什么的?

mro()是做什么的?


来自 django.utils.functional的例子:

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

mro()代表 方法解析次序 。它按搜索方法的顺序返回该类派生自的类型的列表。

mro()__mro__只能在新的样式类上工作。在 Python3中,它们工作起来没有任何问题。然而,在 Python2中,这些类需要从 object继承。

跟着..:

>>> 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__中的第一个类中。

这可能会显示决议的顺序。

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 中删除对该类的第一次提及。

钻石继承的分辨率顺序不同。

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




class B1(A):
def dothis(self):
print('I am from B1 class')
# pass




class B2(object):
def dothis(self):
print('I am from B2 class')
# pass




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




# Diamond inheritance
class D1(B1, B3):
pass




class D2(B1, B2):
pass




d1_instance = D1()
d1_instance.dothis()
# I am from B1 class
print(D1.__mro__)
# (<class '__main__.D1'>, <class '__main__.B1'>, <class '__main__.B3'>, <class '__main__.A'>, <class 'object'>)




d2_instance = D2()
d2_instance.dothis()
# I am from B1 class
print(D2.__mro__)
# (<class '__main__.D2'>, <class '__main__.B1'>, <class '__main__.A'>, <class '__main__.B2'>, <class 'object'>)

以@stryker 为例,C3算法是:

L[D(B,C)] = D + merge(BAo, Co, BC)
= D + B + merge(Ao, Co, C)
= DB + A + merge(o, Co, C)
= DBA + merge(Co, C)
= DBACo

参见 Python 2.3方法解析顺序 | Python. org