2010-01-06 176 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