2010-01-06 31 views
91

django.utils.functional.py“mro()”是做什么的?

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

我不明白mro()。它是做什么的,“mro”是什么意思?

+2

http://www.python.org/download/releases/2.3/mro – GodMan 2012-08-19 20:50:56

+1

Ooph,这是一个很长的阅读。 – paulmelnikow 2015-02-26 00:50:26

回答

164

跟着我。:

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

+7

嗨,alex,D .__ mro__和D.mro()之间有什么区别。 – zjm1126 2010-01-06 03:55:50

+19

'mro'可以通过元类定制,在类初始化时调用一次,结果存储在'__mro__'中 - 参见http://docs.python.org/library/stdtypes.html?highlight=mro# class .__ mro__。 – 2010-01-06 04:24:22

+13

为什么它被称为**方法解析顺序**而不是**属性解析顺序**? – Bentley4 2013-03-24 13:07:39

69

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

mro()__mro__仅适用于新款式。在Python 3中,它们没有任何问题。但在Python 2中,这些类需要从对象继承。

7

这可能会显示分辨率的顺序。

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'>] 

的规则是部门第一在这种情况下将意味着d,B,A,C

的Python通常使用深度优先顺序当搜索继承类 但是,当两个类从同一个类继承时,Python会从mro中删除该类的第一个提及。

+1

因此,您可以看到订单是D,B,A,C – Stryker 2016-03-21 21:57:13

+1

您是指“Python从mro中删除该类的第一个提及”,这是什么意思? – 2017-07-03 23:01:47

+1

@RuthvikVaila:我认为这部分只是说得不好。在这篇关于Python历史的博客文章(http://python-history.blogspot.com/2010/06/method-resolution-order.html)中,Guido van Rossum评论道(关于在Python 2.2中引入的MRO方案)“如果在这个搜索中有任何类别被复制,除**最后一次**之外的所有内容都将从MRO列表中删除”(强调我的)。这意味着它可以删除不仅仅是该课程的第一个“提及”。 – martineau 2017-07-30 16:30:03