जो सवाल मैं पूछने जा रहा हूँ , वह __new__ और __init__ के पायथन के उपयोग की नकल प्रतीत होता है ? है, लेकिन परवाह किए बिना, यह अभी स्पष्ट नहीं मेरे लिए वास्तव में क्या के बीच व्यावहारिक अंतर है __new__और __init__है।
इससे पहले कि आप मुझे यह बताने के लिए दौड़ें कि __new__ऑब्जेक्ट बनाने के लिए है और ऑब्जेक्ट __init__को इनिशियलाइज़ करने के लिए है, मुझे स्पष्ट करने दें: मुझे वह मिल गया है। वास्तव में, वह अंतर मेरे लिए काफी स्वाभाविक है, क्योंकि मेरे पास C ++ में अनुभव है, जहां हमारे पास प्लेसमेंट नया है , जो ऑब्जेक्ट आवंटन को प्रारंभ से अलग करता है।
अजगर सी एपीआई ट्यूटोरियल इस तरह यह बताते हैं:
नए सदस्य प्रकार की वस्तुओं को बनाने के लिए (प्रारंभिक के विपरीत) के लिए जिम्मेदार है। यह
__new__()विधि के रूप में पायथन में उजागर हुआ है । ... एक नई विधि को लागू करने का एक कारण उदाहरण चर के प्रारंभिक मूल्यों को आश्वस्त करना है ।
तो, हाँ - मुझे लगता है कि क्या __new__करता है, लेकिन इसके बावजूद, मुझे अभी भी समझ नहीं आया कि यह पायथन में क्यों उपयोगी है। दिए गए उदाहरण में कहा गया है कि __new__यह उपयोगी हो सकता है यदि आप "उदाहरण चर के प्रारंभिक मूल्यों को आश्वस्त करना चाहते हैं"। खैर, क्या __init__ऐसा नहीं है?
सी एपीआई ट्यूटोरियल में, एक उदाहरण दिखाया गया है जहां एक नया प्रकार (जिसे "नोडी" कहा जाता है) बनाया गया है, और प्रकार का __new__फ़ंक्शन परिभाषित किया गया है। Noddy प्रकार में एक स्ट्रिंग सदस्य होता है जिसे कॉल किया जाता है first, और यह स्ट्रिंग सदस्य किसी रिक्त स्ट्रिंग के लिए आरंभिक होता है जैसे:
static PyObject * Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
.....
self->first = PyString_FromString("");
if (self->first == NULL)
{
Py_DECREF(self);
return NULL;
}
.....
}
ध्यान दें कि __new__यहाँ परिभाषित विधि के बिना , हमें उपयोग करना होगा PyType_GenericNew, जो कि केवल सभी उदाहरण चर सदस्यों को NULL को आरंभ करता है। तो __new__विधि का एकमात्र लाभ यह है कि उदाहरण चर खाली स्ट्रिंग के रूप में शुरू हो जाएगा, जैसा कि NULL के विपरीत है। लेकिन यह कभी क्यों उपयोगी है, क्योंकि अगर हम यह सुनिश्चित करने के बारे में परवाह करते हैं कि हमारे उदाहरण चर कुछ डिफ़ॉल्ट मूल्य के लिए आरंभीकृत हैं, तो हम इस __init__पद्धति में बस कर सकते हैं ?
__new__वह बॉयलरप्लेट नहीं है, क्योंकि बॉयलरप्लेट कभी नहीं बदलता है। कभी-कभी आपको उस विशेष कोड को कुछ अलग करने की आवश्यकता होती है।