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

+1

ओफ, यह कितना लंबा पढ़ा जाता है। – paulmelnikow

उत्तर

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__ में, कोई वर्ग दोहराया गया है मिलता है, और कोई वर्ग अपने पूर्वजों के बाद आता है, को बचाने कि कक्षाएं जो पहले एकाधिक विरासत के समान स्तर पर प्रवेश करती हैं (जैसे कि इस उदाहरण में बी और सी) __mro__ बाएं से दाएं हैं।

प्रत्येक विशेषता जो आपको कक्षा के उदाहरण पर मिलती है, न केवल विधियों, __mro__ के साथ अवधारणात्मक रूप से देखी जाती है, इसलिए, यदि पूर्वजों के बीच एक से अधिक वर्ग उस नाम को परिभाषित करते हैं, तो यह आपको बताता है कि विशेषता कहां मिलेगी - __mro__ में पहली कक्षा में जो उस नाम को परिभाषित करता है।

+7

हाय, एलेक्स, डी .__ mro__ और डी.मोरो() के बीच कोई अंतर है। – zjm1126

+19

'mro' को मेटाक्लास द्वारा अनुकूलित किया जा सकता है, जिसे कक्षा प्रारंभ में एक बार कहा जाता है, और परिणाम' __mro__' में संग्रहीत किया जाता है - http://docs.python.org/library/stdtypes.html?highlight=mro# देखें कक्षा .__ mro__। –

+13

** विशेषता संकल्प आदेश ** के बजाय इसे ** विधि समाधान आदेश ** क्यों कहा जाता है? – Bentley4

69

mro() विधि समाधान आदेश के लिए खड़ा है। यह कक्षाओं से प्राप्त प्रकारों की एक सूची देता है, क्रम में वे विधियों के लिए खोजे जाते हैं।

एमआरओ() या __mro__ केवल नई शैली वर्गों पर काम करता है। पायथन 3 में, वे बिना किसी मुद्दे के काम करते हैं। लेकिन अजगर 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'>] 

शासन होगा विभाग पहला है जो इस मामले में डी, बी, ए, सी

मतलब होगा

अजगर आम तौर पर एक गहराई-प्रथम क्रम का उपयोग करता है जब विरासत वर्ग खोजते हैं, लेकिन जब दो वर्ग एक ही कक्षा से प्राप्त होते हैं, तो पाइथन उस वर्ग के पहले उल्लेख को एमआरओ से हटा देता है।

+1

तो जैसा कि आप ऑर्डर देख सकते हैं डी, बी, ए, सी – Stryker

+1

"पाइथन एमओ से उस वर्ग के पहले उल्लेख को हटा देता है" का क्या मतलब है? –

+1

@RuthvikVaila: मुझे लगता है कि हिस्सा सिर्फ खराब कहा गया है। इस [ब्लॉग पोस्ट] में (http://python-history.blogspot.com/2010/06/method-resolution-order.html) पायथन के इतिहास के बारे में, गिडो वैन रॉसम टिप्पणी (एमआरओ योजना के बारे में पाइथन 2.2 में पेश की गई) "यदि इस खोज में किसी वर्ग को डुप्लिकेट किया गया था, तो ** ** ** ** ** ** ** ** एमआरओ सूची से हटा दिया जाएगा" (जोर मेरा)। इसका तात्पर्य है कि यह कक्षा के पहले "उल्लेख" से अधिक को हटा सकता है। – martineau

संबंधित मुद्दे