मैं हर जगह उदाहरण देखें कि सुपर वर्ग तरीकों से बुलाया जाना चाहिए:अजगर सुपर विधि और बुला विकल्प
SuperClass.method(instance, args)
मैं हर जगह उदाहरण देखें कि सुपर वर्ग तरीकों से बुलाया जाना चाहिए:अजगर सुपर विधि और बुला विकल्प
SuperClass.method(instance, args)
निम्नलिखित परिस्थिति पर विचार एस __init__
छोड़ दिया गया है। इसका कारण यह है कि B
का __init__
A
का __init__
सीधे कॉल करता है।
super
का उद्देश्य विरासत हीरे को हल करना है। आप अन-टिप्पणी
# super(B,self).__init__()
और टिप्पणी बाहर
A.__init__(self)
तो कोड पैदावार अधिक वांछनीय परिणाम:
Running D.__init__
Running B.__init__
Running C.__init__
Running A.__init__
अब सभी __init__
पद्धतियों को बुलाया मिलता है।ध्यान दें कि उस समय जब आप B.__init__
को परिभाषित करते हैं तो आप सोच सकते हैं कि super(B,self).__init__()
A.__init__(self)
पर कॉल करने जैसा ही है, लेकिन आप गलत होंगे। उपर्युक्त स्थिति में, super(B,self).__init__()
वास्तव में C.__init__(self)
पर कॉल करता है।
पवित्र सिगरेट, B
कुछ भी नहीं के बारे में C
जानता है, और अभी तक super(B,self)
कॉल करने के लिए C
के __init__
जानता है? इसका कारण यह है कि self.__class__.mro()
में C
शामिल हैं। दूसरे शब्दों में, self
(या उपर्युक्त में, foo
) C
के बारे में जानता है।
तो सावधान रहें - दोनों कवक नहीं हैं। वे काफी अलग परिणाम प्राप्त कर सकते हैं।
super
has pitfalls. का उपयोग करना विरासत आरेख में सभी वर्गों के बीच समन्वय का एक बड़ा स्तर लेता है। (वे, उदाहरण के लिए, या तो एक ही कॉल हस्ताक्षर __init__
के लिए के बाद से किसी विशेष __init__
पता नहीं है जो अन्य __init__
super
अगले कॉल कर सकते हैं होना चाहिए,, वरना use **kwargs
।) इसके अलावा, आप super
हर जगह का उपयोग कर के बारे में अनुरूप होना चाहिए। इसे एक बार छोड़ दें (उपर्युक्त उदाहरण में) और आप super
के पूरे उद्देश्य को हराते हैं। अधिक नुकसान के लिए लिंक देखें।
यदि आपके वर्ग पदानुक्रम पर पूर्ण नियंत्रण है, या आप विरासत हीरे से बचें, तो super
की आवश्यकता नहीं है।
कोई जुर्माना के रूप में है नहीं है:
super(SuperClass, instance).method(args)
वहाँ करने के लिए किसी भी नुकसान है , हालांकि आपका उदाहरण कुछ हद तक गुमराह है। पहले उदाहरण में, यह
super(SubClass, instance).method(args) # Sub, not SuperClass
होना चाहिए और है कि मुझे सुराग उद्धृत करने के लिए Python docs:
super
के लिए दो विशिष्ट उपयोग के मामलों रहे हैं। एक विरासत के साथ एक वर्ग पदानुक्रम में,super
का उपयोग माता-पिता कक्षाओं को स्पष्ट रूप से नाम दिए बिना संदर्भित करने के लिए किया जा सकता है, इस प्रकार कोड को और अधिक बनाए रखने योग्य बना दिया जा सकता है। यह अन्य प्रोग्रामिंग भाषाओं मेंsuper
के उपयोग की बारीकी से समानता का उपयोग करता है।दूसरा उपयोग केस गतिशील निष्पादन वातावरण में सहकारी एकाधिक विरासत का समर्थन करना है। यह उपयोग केस पायथन के लिए अद्वितीय है और यह स्थिर रूप से संकलित भाषाओं या भाषाओं में नहीं मिलता है जो केवल एकल विरासत का समर्थन करते हैं। इससे "डायमंड आरेख" को कार्यान्वित करना संभव हो जाता है जहां एकाधिक आधार वर्ग एक ही विधि को लागू करते हैं। अच्छा डिज़ाइन यह निर्देश देता है कि इस विधि में प्रत्येक मामले में एक ही कॉलिंग हस्ताक्षर है (क्योंकि कॉल का क्रम रनटाइम पर निर्धारित होता है, क्योंकि वह ऑर्डर कक्षा पदानुक्रम में परिवर्तनों को स्वीकार करता है, और क्योंकि उस क्रम में स्कीलिंग कक्षाएं शामिल हो सकती हैं जो रनटाइम से पहले अज्ञात हैं)।
मूल रूप से, पहली विधि का उपयोग करके आपको एकल श्रेणी के पदानुक्रमों के लिए अपनी मूल कक्षा को हार्ड-कोड नहीं करना पड़ता है, और आप वास्तव में ऐसा नहीं कर सकते जो आप चाहते हैं (कुशलतापूर्वक/प्रभावी) एकाधिक विरासत का उपयोग करते समय दूसरी विधि।
class A(object):
def __init__(self):
print('Running A.__init__')
super(A,self).__init__()
class B(A):
def __init__(self):
print('Running B.__init__')
# super(B,self).__init__()
A.__init__(self)
class C(A):
def __init__(self):
print('Running C.__init__')
super(C,self).__init__()
class D(B,C):
def __init__(self):
print('Running D.__init__')
super(D,self).__init__()
foo=D()
तो कक्षाएं एक तथाकथित विरासत हीरा फार्म:
A
/\
B C
\/
D
कोड पैदावार
Running D.__init__
Running B.__init__
Running A.__init__
ऐसा इसलिए है क्योंकि C
बुरा है 'चल रहा है
क्या मैं इसे सही समझता हूं, एकल विरासत स्थितियों में 'सुपर' का उपयोग करने के लिए कोई विपक्ष नहीं है? सुपर-हानिकारक लिंक के लिए – Wolf
+1। मैं इसे खुद पोस्ट करने वाला था। –
thnx, आपने मेरी गलत धारणा को मंजूरी दे दी है। – 0xc0de
[पायथन का सुपर() सुपर माना जाता है!] (Http://rhettinger.wordpress.com/2011/05/26/super-Considered-super/) दिखाता है कि क्यों और कैसे 'सुपर() 'का उपयोग करें। बीटीडब्ल्यू, नए स्टाइल क्लास और एकाधिक विरासत के साथ आम 'ऑब्जेक्ट' माता-पिता के कारण हमेशा एक विरासत हीरा होता है। – jfs