2010-06-28 12 views
26

मैं समझता हूं कि __init__ और __new__ दोनों काम कैसे करते हैं। मुझे आश्चर्य है कि __init__ कुछ भी है जो __new__ कर सकता है? के रूप में मैं अजगर OO के इस पहलू मेरे सिर में बेहतर फिट करना चाहते हैंपायथन: हमेशा __init__ के बजाय __new__ का उपयोग करें?

class MySubclass(object): 
    def __new__(cls, *args, **kwargs): 
     self = super(MySubclass, cls).__new__(cls, *args, **kwargs) 
     // Do __init__ stuff here 
     return self 

मैं पूछ रहा हूँ:

अर्थात निम्नलिखित पैटर्न द्वारा प्रतिस्थापित किया जा __init__ का उपयोग कर सकते हैं।

+0

संभावित डुप्लिकेट [क्यों परिभाषित '\ _ \ _ new__' और '\ _ \ _ init__' सभी वर्ग में] (http: // stackoverflow।कॉम/प्रश्न/2017876/क्यों-परिभाषित-नई-और-init-all-in-a-class) –

+0

उस विषय पर पुराना प्रश्न: [Python का उपयोग \ _ \ _ new__ और \ _ \ _ init__?] (http://stackoverflow.com/questions/674304/pythons-use-of-new-and-init) –

उत्तर

4

से guido's post (धन्यवाद @ fraca7) एक संभावित जवाब:

उदाहरण के लिए, अचार मॉड्यूल में, __new__ जब वस्तुओं unserializing उदाहरणों बनाने के लिए प्रयोग किया जाता है। इस मामले में, उदाहरण बनाए जाते हैं, लेकिन __init__ विधि लागू नहीं की जाती है।

कोई अन्य समान उत्तर?


मैं अपने खुद के सवाल के रूप में एक 'हां' इस जवाब को स्वीकार कर रहा हूँ:

अगर वहाँ कुछ भी __init__ कर सकते हैं मैं सोच रहा हूँ कि __new__ नहीं?

हाँ, __new__ के विपरीत वे गतिविधियां जो आप __init__ विधि में डाल unpickling प्रक्रिया के दौरान प्रदर्शन नहीं किया जाएगा। __new__ इस भेद को नहीं बना सकता है।

2

ठीक है, Google पर __new__ vs __init__ की तलाश में मुझे this दिखाया गया।

लंबी कहानी लघु, __new__ एक नया ऑब्जेक्ट उदाहरण देता है, जबकि __init__ कुछ भी नहीं देता है और केवल वर्ग के सदस्यों को प्रारंभ करता है।

संपादित करें: वास्तव में अपने प्रश्न का उत्तर देने के लिए, आपको __new__ को ओवरराइड करने की आवश्यकता नहीं है जबतक कि आप अपरिवर्तनीय प्रकारों को उप-वर्गीकृत नहीं कर रहे हैं।

+1

गिडो ने हाल ही में उस बारे में बात की: http://python-history.blogspot.com/2010/06/inside-story- ऑन-न्यू-स्टाइल-क्लासेस.html – fraca7

+2

'__new__' का उपयोग करने के अन्य कारण हैं, उदाहरण के लिए फ्लाईवेट पैटर्न। –

21

तो, एक वर्ग के वर्ग आम तौर पर type है, और जब आप Class() फोन Class के वर्ग पर __call__() विधि है कि संभालती है। मेरा मानना ​​है कि इस तरह type.__call__() कम या ज्यादा कार्यान्वित किया जाता है:

def __call__(cls, *args, **kwargs): 
    # should do the same thing as type.__call__ 
    obj = cls.__new__(cls, *args, **kwargs) 
    if isinstance(obj, cls): 
     obj.__init__(*args, **kwargs) 
    return obj 

अपने सवाल का सीधा जवाब नहीं, चीजें हैं जो __init__() कर सकते हैं (परिवर्तन/"प्रारंभ" एक निर्दिष्ट उदाहरण) चीजों में से एक सबसेट है कि __new__() कर सकते हैं (जो भी ऑब्जेक्ट चाहता है उसे बनाएं या अन्यथा चुनें, ऑब्जेक्ट लौटने से पहले उस वस्तु को कुछ भी करना चाहिए)।

हालांकि, दोनों तरीकों का उपयोग करने के लिए सुविधाजनक है। __init__() का उपयोग सरल है (इसे कुछ भी बनाना नहीं है, इसे कुछ भी वापस करने की ज़रूरत नहीं है), और मेरा मानना ​​है कि __init__() का उपयोग करने के लिए हमेशा सर्वोत्तम अभ्यास है जब तक आपके पास __new__() का उपयोग करने का कोई विशिष्ट कारण न हो।

+0

मेरे लिए, यह वास्तव में ओपी के प्रश्न का उत्तर नहीं देता है। आपने कहा था कि "__init __()' चीजें जो चीजें कर सकती हैं वह उन चीजों का सबसेट है जो '__new __()' कर सकती हैं ", लेकिन यह ओपी का मुद्दा है, है ना? यदि वह वाक्य सत्य है, तो '__init __()' को सुरक्षित रूप से बहिष्कृत किया जा सकता है, क्योंकि यह कुछ भी कर सकता है, '__new __()' बस भी कर सकता है। – Ray

+0

@ रे ** आपका निष्कर्ष आपके आधार से पालन करने में विफल रहता है। ** जबकि वह वाक्य * स्पष्ट रूप से सत्य है, '__init __()' को सभी स्पष्ट कारणों से सुरक्षित रूप से बहिष्कृत नहीं किया जा सकता है - विशेष रूप से, ** (ए) ** मौजूदा पायथन पारिस्थितिकी तंत्र * और * ** (बी) ** के साथ पिछड़े संगतता को संरक्षित करने की आवश्यकता ** '__nit __()' एपीआई की संविदात्मक नाजुकता (जिसका डिज़ाइन अनिवार्य रूप से लौटाया जाता है) '__init __() ' एपीआई (जिसका डिजाइन ऐसी बाधाओं को लागू नहीं करता है)। '__new __()' एपीआई उल्लंघनों को आमंत्रित करता है, जो खराब है; '__init __()' करता है * नहीं *, जो अच्छा है। –

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