2010-03-08 14 views
209
class A: 
def __init__(self): 
    print "world" 

class B(A): 
def __init__(self): 
    print "hello" 

B() 
hello 

अन्य सभी भाषाओं में मैंने सुपर कन्स्ट्रक्टर के साथ काम किया है, इसे पूरी तरह से बुलाया गया है। पाइथन में इसे कैसे आमंत्रित किया जाता है? मैं super(self) की अपेक्षा करता हूं लेकिन यह काम नहीं करता है।सुपर कन्स्ट्रक्टर का आह्वान कैसे करें?

+0

[पाइथन में चेन-कॉलिंग पेरेंट कन्स्ट्रक्टर] के संभावित डुप्लिकेट (http://stackoverflow.com/questions/904036/chain-calling-parent-constructors-in-python) –

उत्तर

232

super() नई शैली की कक्षाओं में एक माता पिता की तरह वस्तु रिटर्न:

class A(object): 
    def __init__(self): 
     print "world" 

class B(A): 
    def __init__(self): 
     print "hello" 
     super(B, self).__init__() 

B() 
+42

जिज्ञासा की बस 'सुपर (बी , स्वयं) 'बी और आत्म दोनों का उल्लेख किया जाना चाहिए? यह अनावश्यक नहीं है? स्वयं को पहले बी के संदर्भ में नहीं होना चाहिए? – Mike

+75

नहीं, क्योंकि 'स्वयं' वास्तव में 'बी' का एक बच्चा 'सी' का उदाहरण हो सकता है। –

+0

क्या होगा यदि बी (ए, एए) '? मैं देखता हूं कि 'सुपर (बी, स्वयं)' ए 'रिटर्न देता है, लेकिन फिर आपको' एए 'कैसे मिलता है? –

47
पायथन 2.x पुरानी शैली कक्षाओं के साथ

यह इस होगा:

class A: 
def __init__(self): 
    print "world" 

class B(A): 
def __init__(self): 
    print "hello" 
    A.__init__(self) 
+0

यह नई शैली कक्षाओं के लिए काम नहीं करेगा? – kdbanman

+4

@kdbanman: यह नए शैली के वर्गों के साथ काम करेगा, लेकिन नए शैली के वर्गों का उपयोग करने के कारणों में से एक यह है कि इसे इस तरह से नहीं करना है। आप 'सुपर' का उपयोग कर सकते हैं और जिस श्रेणी से आप विरासत में हैं, उसे सीधे नामित नहीं करना है। – Gabe

28

एक ही रास्ता है ए के कन्स्ट्रक्टर को कॉल करने और self को एक तर्क के रूप में पास करने के लिए,

class B(A): 
    def __init__(self): 
     A.__init__(self) 
     print "hello" 

इस शैली का लाभ यह है कि यह बहुत स्पष्ट है। यह ए के कन्स्ट्रक्टर को कॉल करता है। नकारात्मकता यह है कि यह हीरे के आकार की विरासत को बहुत अच्छी तरह से संभाल नहीं पाती है, क्योंकि आप साझा बेस क्लास के कन्स्ट्रक्टर को दो बार कॉल करना समाप्त कर सकते हैं।

अन्य तरीका सुपर() का उपयोग करना है, जैसा कि अन्य ने दिखाया है। एकल विरासत के लिए, यह मूल रूप से वही बात करता है जैसे आप माता-पिता के निर्माता को कॉल करते हैं।

हालांकि, सुपर() काफी हद तक जटिल है और कभी-कभी कई विरासत स्थितियों में प्रति-सहज हो सकता है। प्लस तरफ, सुपर() हीरा के आकार की विरासत को संभालने के लिए इस्तेमाल किया जा सकता है। यदि आप सुपर() करते हैं, तो मुझे पता है कि सुपर() काम कितना सुपर() काम करता है, here (हालांकि मैं उस लेख की राय का समर्थन नहीं कर रहा हूं) के बारे में जानना चाहता हूं।

86

अन्य उत्तर के साथ लाइन में, वहाँ तथापि अजगर-3.x में प्रक्रिया को सरल बनाया गया है, (निर्माता सहित) सुपर वर्ग तरीकों कॉल करने के लिए कई तरीके हैं:

अजगर-2.x

class A(object): 
def __init__(self): 
    print "world" 

class B(A): 
def __init__(self): 
    print "hello" 
    super(B, self).__init__() 

अजगर-3.x

class A(object): 
def __init__(self): 
    print("world") 

class B(A): 
def __init__(self): 
    print("hello") 
    super().__init__() 

super() अब के अनुसार super(<containing classname>, self) के बराबर है।

4

मैं निम्न सूत्र है कि पिछले जवाब फैली का उपयोग करें:

class A(object): 
def __init__(self): 
    print "world" 

class B(A): 
def __init__(self): 
    print "hello" 
    super(self.__class__, self).__init__() 

B() 

इस तरह आप सुपर करने के लिए कॉल में वर्ग के नाम को दोहराने की जरूरत नहीं है। यदि आप बड़ी संख्या में कक्षाओं को कोड कर रहे हैं, तो यह आसान हो सकता है, और कक्षा कोड से स्वतंत्र कन्स्ट्रक्टर विधियों में अपना कोड बनाना चाहता है।

+4

लेकिन बी 'ए' के ​​बजाय 'बी' का विस्तार करने का निर्णय लेते हैं, और 'स्वयं (__) 'अंक' बी (ए) 'के बजाय' सी (बी)' के लिए 'सी' (बी) 'को चुनने का निर्णय लेते हैं, तो' सुपर (स्वयं .__ वर्ग__ ' स्वयं) '' ए 'के बजाय 'बी' पर वापस इंगित करता है। – dened

+7

जब आप 'बी' उप-वर्ग करते हैं तो यह अनंत रिकर्सन त्रुटियों का कारण बन जाएगा। ** ** ** नहीं 'स्वयं .__ वर्ग__' या' प्रकार (स्वयं) 'का उपयोग करें, या तो एक स्पष्ट वर्ग ('बी') में पास करें या पाइथन 3 में, बिना तर्क के' सुपर()' का उपयोग करें। –

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