"मेरो ()" क्या करता है?


जवाबों:


211

साथ चलो...:

>>> 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__कि उस नाम को परिभाषित करता है।


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

26
mroमेटाक्लाज़ द्वारा अनुकूलित किया जा सकता है, इसे क्लास इनिशियलाइज़ेशन में एक बार कहा जाता है, और परिणाम को इसमें संग्रहीत किया जाता है __mro__- देखें docs.python.org/library/…
एलेक्स मार्टेली

23
विशेषता रिज़ॉल्यूशन ऑर्डर के बजाय इसे विधि रिज़ॉल्यूशन ऑर्डर क्यों कहा जाता है ?
बेंटले 4

1
वैसे ही जैसे @Alex Martelli कहा और की सामग्री python-history.blogspot.com/2010/06/... , एमआरओ विशेषता जब नया वर्ग के रूप में ही उपयोग किया जाता है ऐड होना चाहिए जब अजगर 2.2 एमआरओ और अजगर 2.3 एमआरओ (सी 3) उपयोग किया जाता है।
andy

82

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

mro () या __mro__ केवल नई शैली की कक्षाओं पर काम करता है। अजगर 3 में, वे बिना किसी मुद्दे के काम करते हैं। लेकिन अजगर 2 में उन वर्गों से विरासत में प्राप्त करने की आवश्यकता है object


10

यह शायद संकल्प का क्रम दिखाएगा।

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
तो जैसा कि आप देख सकते हैं कि आदेश डी, बी, ए, सी
स्ट्राइकर

1
आपका क्या मतलब है "पायथन उस वर्ग का पहला उल्लेख mro से हटाता है।"
Ruthvik Vaila

2
@RuthvikVaila: मुझे लगता है कि हिस्सा सिर्फ खराब कहा गया है। पायथन के इतिहास के बारे में इस ब्लॉग पोस्ट में, गुइडो वैन रोसुम टिप्पणी (पायथन 2.2 में शुरू की गई एमआरओ योजना के बारे में) "यदि इस खोज में किसी भी वर्ग को दोहराया गया था, लेकिन अंतिम घटना को एमआरओ सूची (जोर मेरा) से हटा दिया जाएगा। )। इसका तात्पर्य यह है कि यह वर्ग के पहले "उल्लेख" से अधिक को हटा सकता है।
मार्टीनो

1

हीरे की विरासत में रिज़ॉल्यूशन का क्रम अलग होगा।

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

लेकिन संकल्प अलग क्यों है?
वादिम

एकाधिक वंशानुक्रम परिदृश्य में, किसी भी निर्दिष्ट विशेषता को वर्तमान कक्षा में पहले खोजा जाता है। यदि नहीं मिला है, तो दो बार समान कक्षा खोजे बिना गहराई-पहले, बाएं-दाएं फैशन में पैरेंट क्लासेस में खोज जारी रहती है।
गिरीश गुप्ता

क्षमा करें, लेकिन मुझे समझ में नहीं आता है कि पहले मामले में यह क्यों होता है, class B3लेकिन दूसरे मामले में इसके class Aबाद जाना हैclass B1
वादिम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.