दिलचस्प पोस्ट
जावा में एन्कोडिंग यूआरएल क्वेरी पैरामीटर पंडों से जटिल मानदंडों के साथ चयन करना। डेटाफ़्रेम क्या मैं एक डॉकर कंटेनर में एकाधिक प्रोग्राम चला सकता हूं? स्विंग HTML के लिए जार से छवियां लोड करना jQuery के मोबाइल लॉक अभिविन्यास सीमा चौड़ाई की तुलना में सीमा लंबाई छोटा? SQL सर्वर – एक संग्रहीत कार्यविधि समाप्त होने तक तालिका को लॉक कैसे करें AngularJS का उपयोग करते समय पृष्ठ पर प्रदर्शित होने के लिए मैं कुरकुरा ब्रेस कैसे बचा सकता हूं? स्कला में एक फाइल को कैसे लिखना है? सी # में बूल और बूलियन प्रकारों के बीच अंतर क्या है आधार वर्ग के <<सूची के लिए व्युत्पन्न वर्ग के <> सूची का कास्टिंग MySQL में दो डेटासेट के बीच अंतर की गणना करें क्या मैं मार्कडाउन में 'target = "_ blank"' के साथ लिंक बना सकता हूं? git: एक्स शाखा द्वारा आपकी शाखा आगे है सी ++ में, आभासी आधार वर्ग क्या है?

एक निर्माता के रूप में __init__?

पायथन में कूदो –

यह आकर्षक होगा, लेकिन इसे कक्षा के निर्माता को कॉल करने में गलत होगा। यह मोहक है, क्योंकि यह एक निर्माता की तरह दिखता है (सम्मेलन द्वारा, __init__ क्लास के लिए परिभाषित पहली विधि है), एक (यह कक्षा के एक नव निर्मित उदाहरण में निष्पादित कोड का पहला टुकड़ा है) जैसी कार्य करता है, और यहां तक ​​कि एक की तरह लगता है ("Init" निश्चित रूप से एक निर्माता- ish प्रकृति का सुझाव देता है) गलत, क्योंकि वस्तु पहले से ही __init__ के नाम से __init__ है, और आपको पहले से कक्षा के नए इंस्टेंस के लिए एक वैध संदर्भ है।

भाव से पता चलता है कि __init__ को कंसट्रक्टर के रूप में कॉल करना गलत है क्योंकि ऑब्जेक्ट पहले से ही __init__ नामक समय से बना है। परंतु! मैं हमेशा इस धारणा के तहत रहा हूं कि निर्माता को वस्तु के निर्माण के बाद ही बुलाया जाता है क्योंकि इसका इस्तेमाल मूल रूप से डेटा के सदस्यों को आरंभ करने के लिए किया जाता है, जो उस वस्तु को नहीं समझ पाएगा, यदि ऑब्जेक्ट समय के निर्माता से मौजूद नहीं था ? (सी ++ / जावा पृष्ठभूमि से आ रहा है)

वेब के समाधान से एकत्रित समाधान "एक निर्माता के रूप में __init__?"

यदि आपके पास एक क्लास Foo :

  • Foo() कन्स्ट्रक्टर है
  • Foo.__init__() प्रारंभकर्ता है
  • Foo.__new__() आवंटक है

एक पायथन ऑब्जेक्ट का निर्माण केवल एक नए उदाहरण का आवंटन है, जिसके बाद कहा हुआ इंस्टालेशन का आरम्भिकरण किया गया है।

निजी रूप से, मुझे लगता है कि " __init__ एक कन्स्ट्रक्टर नहीं है" सुंदर बाल विभाजन करने के लिए।

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

एक नया ऑब्जेक्ट का अनुरोध किया जाता है जब एक C ++ कन्स्ट्रक्टर कहा जाता है। यह नई ऑब्जेक्ट पर फ़ील्ड को असाइन करने के लिए अपने तर्कों का उपयोग करना माना जाता है, जैसे ऑब्जेक्ट की सामान्य ऑपरेशन के लिए आवश्यक अपरिएंट सेट अप किए जाते हैं। ऑब्जेक्ट पहले से ही एक वैध पूर्व-मौजूदा स्थान है, जो कि कंस्ट्रक्टर का कोड शुरू हो रहा है, तब तक फ़ील्ड को संग्रहीत करता है। नए ऑब्जेक्ट में पहले से ही सभी घोषित फ़ील्ड हैं, जब कंस्ट्रक्टर में कोड चलना शुरू होता है, लेकिन इसमें कचरा होता है।

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

एक __init__ विधि और एक सी + + / जावा कन्स्ट्रक्टर के बीच का मुख्य अंतर मैंने उस आखिरी वाक्य में प्रकाशित किया है, और यह जावा / सी ++ की स्थिर प्रकृति और पायथन की गतिशील प्रकृति के बीच का अंतर है। मुझे नहीं लगता कि यह वारंट उन्हें मौलिक अलग-अलग अवधारणाओं को बुलाता है, जिन्हें एक ही शब्द द्वारा संदर्भित नहीं किया जाना चाहिए।

मुझे लगता है कि मुख्य कारण अजगरवादक, कंसट्रक्टर के रूप में __इनट_ को संदर्भित करना पसंद नहीं करते हैं कि लोगों को सी ++ / जावा कन्स्ट्रक्टरों के बारे में "एक नया ऑब्जेक्ट बनाने" के रूप में सोचना है, क्योंकि जब आप उन्हें कॉल करते हैं तो ऐसा ही करते हैं। लेकिन वास्तव में दो बातें चल रही हैं जब आप एक निर्माता कॉल करते हैं; एक नया ऑब्जेक्ट बनाया जाता है और फिर इसे शुरू करने के लिए कन्स्ट्रक्टर को कहा जाता है। सी ++ / जावा में "एक नया ऑब्जेक्ट बनाएं" का हिस्सा अदृश्य है, जबकि इसे पायथन में ( __new__ विधि के माध्यम से) उजागर किया जा सकता है।

इसलिए जबकि __init__ पद्धति की भूमिका सी ++ / जावा कन्स्ट्रक्टर की भूमिका के समान है, कुछ लोग इस तथ्य पर जोर देना पसंद करते हैं कि यह पूरी प्रक्रिया नहीं कह रही है कि " __init__ कन्स्ट्रक्टर नहीं है"

निर्माता एक उदाहरण देता है और विफल हो सकता है लेकिन __init__ एक उदाहरण वापस नहीं करता है। यहां तक ​​कि जब __init__ उठता है और अपवाद, __del__ को उदाहरण नष्ट करने के लिए कहा जाता है।

यह यहां देखा जा सकता है:

 class A(object): def __init__(self): raise ValueError def __del__(self): print "Called" def main(): try: a = A() except ValueError, e: print "ValueError" if __name__ == '__main__': main() 

दूसरी ओर __new__ , एक उदाहरण देता है।

जॉन जेले से "प्रोग्रामिंग पायथन: परिचय कंप्यूटर कंप्यूटर" में कहा गया है, " विशेष विधि __init__ ऑब्जेक्ट कन्स्ट्रक्टर है । पायथन एक नया ऑब्जेक्ट को इनिशियलाइज़ करने के लिए इस विधि को कहता है। __init__ की भूमिका एक उदाहरण के चर के लिए प्रारंभिक मान प्रदान करना है वस्तु। "

http://www.programiz.com/article/python-self-why से

__init__() एक निर्माता नहीं है

[..] एक महत्वपूर्ण निष्कर्ष [..] यह है कि, __init__() एक निर्माता नहीं है। कई __init__() अजगर प्रोग्रामर इसके साथ उलझन में हैं क्योंकि __init__() को एक वस्तु बनाते समय कहा जाता है। एक करीब से निरीक्षण यह प्रकट करेगा कि __init__() में पहला पैरामीटर ऑब्जेक्ट ही है (वस्तु पहले से मौजूद है)। वस्तु __init__() को तत्काल कहा जाता है और वस्तु को प्रारंभ करने के लिए प्रयोग किया जाता है।

तकनीकी तौर पर, कन्स्ट्रक्टर एक ऐसा तरीका है जो वस्तु को खुद बना देता है। अजगर में, यह विधि __new__() । इस विधि का एक आम हस्ताक्षर है

__new__(cls, *args, **kwargs)

बेन द्वारा दिए गए answert के बारे में, मैं बहस करूँगा कि ज्यादातर भाषाओं इस परिभाषा (पूरी तरह से) का पालन नहीं करते हैं

इसके अलावा:

जब __new__() को कहा जाता है, तो क्लास खुद ही पहली तर्क के रूप में पारित हो जाता है यह वही है जो उपरोक्त हस्ताक्षर में cls लिए है। फिर, self तरह, cls सिर्फ एक नामकरण सम्मेलन है। इसके अलावा, *args और **kwargs का इस्तेमाल अजगर में विधि कॉल के दौरान आर्बिट्री संख्या तर्कों के लिए किया जाता है।

__new__() को लागू करते समय याद रखने के लिए कुछ महत्वपूर्ण चीजें हैं:

  1. __new__() हमेशा __new__() से पहले कहा जाता है।
  2. पहला तर्क यह है कि वह क्लास ही है जिसे पारस्परिक रूप से पारित किया गया है।
  3. हमेशा __new__() से एक वैध ऑब्जेक्ट वापस। अनिवार्य नहीं है, लेकिन यह पूरे बिंदु पर है।

बॉटमलाइन (मेरे लिए): __new__() प्रतीत होता है, नहीं __init__() यद्यपि सभी व्यावहारिक तरीकों से __init__() जो अधिकांश लोग सोचते हैं कि एक कन्स्ट्रक्टर क्या करेगा, उसका भाग होता है।

__init__ एक कन्स्ट्रक्टर नहीं है, लेकिन उन कारणों के लिए जो आपको पायथन के रूप में सीखने के साथ कोई फर्क नहीं पड़ेगा यह आपके द्वारा सी ++ और जावा में कंसल्टर्स के व्यवहार के लिए उपयोग किए जाने के तरीके का व्यवहार करता है।