दिलचस्प पोस्ट
सी # में एक रजिस्ट्री मान को कैसे हटाएं अपनी सामग्री के सटीक मिलान के आधार पर तत्व चुनें नकारात्मक मूल्यों के साथ मॉड्यूलो ऑपरेटर PHP में पूर्णांक सूचकांक द्वारा एक एसोसिएटिव सरणी तक पहुंच एसएफटीपी और "एफ़टीपी ओवर एसएसएच" के बीच अंतर मैं दो अलग एंड्रॉइड ऐप्स पर साझा की गई फ़ाइलों को साझा कैसे कर सकता / सकती हूं? HTML5: कैमरा पहुंच नाम 'मॉडल' मौजूदा संदर्भ में MVC3 में मौजूद नहीं है स्विफ्ट – संपत्ति पर कस्टम सेटर पायथन स्मृति लीक एंड्रॉइड नया नीचे नेविगेशन बार फेसबुक sdk का उपयोग कर ऐप के लिए हैश कुंजी जनरेट कर रहा है जावा थोड़ा endian या बड़े endian में integers पढ़ा है? सशर्त अभिव्यक्ति का प्रकार निर्धारित नहीं किया जा सकता क्योंकि 'string' और 'System.DBNull' के बीच कोई अंतर्निहित रूपांतरण नहीं है जावास्क्रिप्ट में एक पहले से ही बाध्य कार्य के अधिक तर्क बाँधें

अजगर का "सुपर" सही काम कैसे करता है?

मैं पायथन 2.5 चला रहा हूं, इसलिए यह प्रश्न पायथन 3 पर लागू नहीं हो सकता है। जब आप कई विरासत का इस्तेमाल करते हुए डायरेक्ट क्लास पदानुक्रम बनाते हैं और व्युत्पन्न अधिकांश वर्ग के ऑब्जेक्ट को बनाते हैं, तो पायथन राइट थिंग (टीएम) करता है। यह व्युत्पन्न -अधिकतम वर्ग के लिए कन्स्ट्रक्टर को कॉल करता है, फिर बाएं से दाएं सूचीबद्ध के रूप में उसके मूल कक्षाएं, फिर दादा-दादी मैं पायथन एमआरओ से परिचित हूं; यह मेरा प्रश्न नहीं है मैं उत्सुक हूँ कि कैसे सुपर से लौटा वस्तु वास्तव में माता-पिता कक्षाओं में सुपर की कॉल करने के लिए सही क्रम का प्रबंधन करती है I इस उदाहरण कोड पर विचार करें:

#!/usr/bin/python class A(object): def __init__(self): print "A init" class B(A): def __init__(self): print "B init" super(B, self).__init__() class C(A): def __init__(self): print "C init" super(C, self).__init__() class D(B, C): def __init__(self): print "D init" super(D, self).__init__() x = D() 

यह कोड सहज ज्ञान युक्त काम करता है, यह प्रिंट करता है:

 D init B init C init A init 

हालांकि, यदि आप बी के इनिट फ़ंक्शन में सुपर को कॉल करते हैं, तो न तो ए और सी के इनट फ़ंक्शन को कहा जाता है। इसका मतलब यह है कि बी के सुपर को कॉल किसी तरह सी वर्ग के पदानुक्रम में सी के अस्तित्व के बारे में जागरूक है। मुझे पता है कि सुपर ओवरलोडेड ऑपरेटर के साथ एक प्रॉक्सी ऑब्जेक्ट देता है, लेकिन डी के इनिट डेफिनेशन में सुपर द्वारा लौटा वस्तु कैसे सी की मौजूदगी को बी के इनिट परिभाषा में सुपर द्वारा लौटा वस्तु के साथ संवाद करती है? क्या जानकारी उस सुपर उपयोग की अगली कॉल की वस्तु पर संग्रहीत है? यदि हां, तो सुपर के बजाय सुपर क्यों नहीं है?

संपादित करें: जेके ने सही ढंग से बताया कि यह स्वयं नहीं है। सुपर इसलिए कि सुपर क्लास का एक विशेषता है, क्लास का उदाहरण नहीं। संकल्पनात्मक रूप से यह समझ में आता है, लेकिन व्यवहार में सुपर भी कक्षा का एक गुण नहीं है! आप दो वर्गों ए और बी बनाकर दुभाषिया में इसका परीक्षण कर सकते हैं, जहां बी बी से विरासत में आते हैं, और dir(B) फोन करते हैं। इसमें कोई super या __super__ super __super__ विशेषता नहीं है

Solutions Collecting From Web of "अजगर का "सुपर" सही काम कैसे करता है?"

मैंने नीचे दिए गए लिंक का एक गुच्छा प्रदान किया है, जो आपके प्रश्न का अधिक विस्तार से और अधिक सटीकता से जवाब देने से मैं कभी भी उम्मीद कर सकता हूं मैं आपके प्रश्न का उत्तर अपने ही शब्दों में दे सकता हूं, ताकि आप कुछ समय बचा सकें। मैं इसे अंक में रखूंगा –

  1. सुपर एक निर्मित फ़ंक्शन है, एक विशेषता नहीं
  2. पायथन में हर प्रकार (कक्षा) में एक __mro__ विशेषता है, जो उस विशिष्ट उदाहरण के विधि संकल्प आदेश को संग्रहीत करता है।
  3. सुपर को प्रत्येक कॉल फॉर्म सुपर (प्रकार [, ऑब्जेक्ट-या-प्रकार]) का है। मान लीजिए कि दूसरी विशेषता क्षण के लिए एक वस्तु है।
  4. सुपर कॉल्स के शुरुआती बिंदु पर ऑब्जेक्ट ड्रिवर क्लास ( डीसी ) कहते हैं
  5. एमआरओ में कक्षाओं में मेल खाने वाले तरीकों के लिए सुपर लग रहा है, पहली तर्क के रूप में वर्णित कक्षा के बाद (इस मामले में डीसी के बाद कक्षाएं)।
  6. जब मिलान विधि मिलती है (वर्ग बीसी 1 में कहते हैं), इसे कहा जाता है।
    (यह विधि सुपर का उपयोग करनी चाहिए, इसलिए मैं यह मानता हूं – पायथन की सुपर निफ्टी देखें, लेकिन इसका इस्तेमाल नहीं किया जा सकता है – नीचे दिए गए लिंक) उस विधि के बाद ऑब्जेक्ट की क्लास 'एमआरओ में अगले विधि के लिए एक खोज का कारण बनता है बीसी 1
  7. जब तक सभी विधियों पाए जाते हैं और बुलाया जाता है तब तक दोहराएँ धोएं।

आपके उदाहरण के लिए स्पष्टीकरण

  MRO: D,B,C,A,object 
  1. super(D, self).__init__() कहा जाता है। ईस्टेंस (आत्म, डी) => सच है
  2. डी के दाईं ओर वर्गों में एमआरओ में अगली विधि खोजें

    B.__init__ पाया और कहा जाता है

  3. B.__init__ कॉल्स super(B, self).__init__()

    इस्टेंस (आत्म, बी) => झूठी
    ईस्टेंस (आत्म, डी) => सच है

  4. इस प्रकार, एमआरओ एक ही है, लेकिन बी की सी, ए के अधिकार में खोज जारी है, ऑब्जेक्ट एक के बाद एक की खोज की जाती है। अगले __init__ पाया जाता है __init__

  5. इत्यादि इत्यादि।

सुपर का स्पष्टीकरण
http://www.python.org/download/releases/2.2.3/descrintro/#cooperation
सुपर का उपयोग करते समय देखने के लिए चीजें
http://fuhm.net/super-harmful/
पायथन एमआरओ एल्गोरिदम:
http://www.python.org/download/releases/2.3/mro/
सुपर डॉक्स:
http://docs.python.org/library/functions.html
इस पृष्ठ के नीचे सुपर पर एक अच्छा अनुभाग है:
http://docstore.mik.ua/orelly/other/python/0596001886_pythonian-chp-5-sect-2.html

मुझे उम्मीद है कि यह इसे साफ़ करने में मदद करेगा

अपना कोड इस पर बदलें और मुझे लगता है कि यह चीजों को समझाएगा (संभवतः super जहां, कहें, B __mro__ ?):

 class A(object): def __init__(self): print "A init" print self.__class__.__mro__ class B(A): def __init__(self): print "B init" print self.__class__.__mro__ super(B, self).__init__() class C(A): def __init__(self): print "C init" print self.__class__.__mro__ super(C, self).__init__() class D(B, C): def __init__(self): print "D init" print self.__class__.__mro__ super(D, self).__init__() x = D() 

यदि आप इसे चलाते हैं तो आप देखेंगे:

 D init (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>) B init (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>) C init (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>) A init (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>) 

इसके अलावा यह पाइथन सुपर का पता लगाने के लिए निपुण है, लेकिन आप इसका उपयोग नहीं कर सकते ।

सिर्फ अनुमान:

सभी चार तरीकों में self समान वस्तु का संदर्भ देते हैं, जो कि कक्षा D । अतः, B.__init__() , कॉल को super(B,self) को super(B,self) के पूरे हीरे वंश को जानता है और इसे 'बाद' B से विधि प्राप्त करना होगा। इस मामले में, यह C क्लास है।

super() पूर्ण वर्ग पदानुक्रम को जानता है बी के इनिट के अंदर ऐसा होता है:

 >>> super(B, self) <super: <class 'B'>, <D object>> 

यह केंद्रीय प्रश्न को हल करता है,

डी के इनिट परिभाषा में सुपर द्वारा लौटा वस्तु कैसे सी के अस्तित्व को बी के इनिट परिभाषा में सुपर द्वारा लौटा वस्तु को सूचित करती है?

अर्थात्, बी की init परिभाषा में, self D का एक उदाहरण है, और इस प्रकार C के अस्तित्व को संप्रेषित करता C । उदाहरण के लिए C type(self).__mro__ में पाया जा सकता है

याकूब के जवाब से पता चलता है कि समस्या को कैसे समझा जाए, जबकि बल्टरबर्ट विवरण दिखाता है और एचआरआर बिंदु पर सीधे चला जाता है।

एक बात जो वे आपके प्रश्न से (कम से कम स्पष्ट नहीं) को कवर नहीं करते, यह मुद्दा है:

हालांकि, यदि आप बी के इनिट फ़ंक्शन में सुपर को कॉल करते हैं, तो न तो ए और सी के इनट फ़ंक्शन को कहा जाता है।

यह समझने के लिए, ए के इनिट पर स्टैक मुद्रित करने के लिए याकूब का कोड बदलें, नीचे दिए गए अनुसार:

 import traceback class A(object): def __init__(self): print "A init" print self.__class__.__mro__ traceback.print_stack() class B(A): def __init__(self): print "B init" print self.__class__.__mro__ super(B, self).__init__() class C(A): def __init__(self): print "C init" print self.__class__.__mro__ super(C, self).__init__() class D(B, C): def __init__(self): print "D init" print self.__class__.__mro__ super(D, self).__init__() x = D() 

यह थोड़ा आश्चर्य की बात है कि B की रेखा super(B, self).__init__() वास्तव में C.__init__() कॉल C.__init__() रहा C.__init__() , क्योंकि C B का आधार वाला नहीं है

 D init (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>) B init (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>) C init (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>) A init (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>) File "/tmp/jacobs.py", line 31, in <module> x = D() File "/tmp/jacobs.py", line 29, in __init__ super(D, self).__init__() File "/tmp/jacobs.py", line 17, in __init__ super(B, self).__init__() File "/tmp/jacobs.py", line 23, in __init__ super(C, self).__init__() File "/tmp/jacobs.py", line 11, in __init__ traceback.print_stack() 

ऐसा इसलिए होता है क्योंकि super (B, self) ' बी' के बेसक्लास संस्करण को ' __init__ ' नहीं कह रहा है । इसके बजाय, यह ' B ' के दायीं ओर प्रथम श्रेणी पर __mro__ जो कि self के __mro__ पर मौजूद है और इसमें एक विशेषता है

इसलिए, यदि आप बी के B.__init__ फ़ंक्शन में सुपर को कॉल करते हैं , तो विधि स्टैक B.__init__ पर बंद हो जाएगा, और कभी भी C या A तक नहीं पहुंचेंगे

संक्षेप में:

  • भले ही किस वर्ग की बात हो रही है, self हमेशा इस उदाहरण के संदर्भ में होता है, और इसका __mro__ और __class__ स्थिर रहता है
  • सुपर () विधि को उन कक्षाओं को __mro__ जो वर्तमान __mro__ पर मौजूद के दाईं ओर हैं __mro__ जैसा कि __mro__ स्थिर रहता है, क्या होता है कि यह एक सूची के रूप में खोजा जाता है, वृक्ष या ग्राफ के रूप में नहीं।

उस आखिरी बिंदु पर, ध्यान रखें कि एमआरओ के एल्गोरिदम का पूरा नाम सी 3 सुपरक्लास रैखिकरण है । यही है, यह उस सूची को एक सूची में समतल करता है। जब विभिन्न super() कॉल्स होते हैं, तो वे प्रभावशाली ढंग से उस सूची को दोहराते हैं।