2009-07-10 9 views
7

मैं इस बारे में सोच रहा हूं कि मैं पायथन में कक्षाएं कैसे लिखता हूं। अधिक विशेष रूप से कैसे निर्माता को कार्यान्वित किया जाता है और वस्तु को कैसे नष्ट किया जाना चाहिए। मैं ऑब्जेक्ट क्लीनअप करने के लिए सीपीथॉन के संदर्भ गिनती पर भरोसा नहीं करना चाहता हूं। यह मूल रूप से मुझे बताता है कि मुझे अपने ऑब्जेक्ट जीवनकाल को प्रबंधित करने के लिए बयानों के साथ उपयोग करना चाहिए और मुझे एक स्पष्ट बंद/निपटान विधि की आवश्यकता है (यदि ऑब्जेक्ट एक संदर्भ प्रबंधक भी है तो इस विधि को __exit__ से बुलाया जा सकता है)।क्या __del__ में ऑब्जेक्ट को बंद करने/निपटाने के लिए वास्तव में ठीक है?

class Foo(object): 
    def __init__(self): 
     pass 
    def close(self): 
     pass 

अब, मेरे सभी वस्तुओं इस तरह से व्यवहार और मेरे सारे कोड close() (या dispose()) को बयान या स्पष्ट कॉल के साथ उपयोग करता है मैं वास्तव में जरूरत नहीं दिख रहा है मुझे __del__ में किसी भी कोड डालने के लिए है। क्या हमें वास्तव में हमारी वस्तुओं का निपटान करने के लिए __del__ का उपयोग करना चाहिए?

+2

मैं ऑब्जेक्ट क्लीनअप करने के लिए सीपीथॉन के संदर्भ गिनती पर भरोसा नहीं करना चाहता हूं। धरती पर क्यों नहीं? वस्तु संदर्भ गिनती के साथ क्या गलत है? –

+0

@ एसएलओटी, संदर्भ गिनती सिर्फ वहां नहीं है यदि आप अपने कोड को पर्यावरण के साथ अधिक उन्नत कचरा संग्रह, जैसे कि ज्योथन या आयरनपीथन के साथ ले जाएं - और यदि एक दिन सीपीथन (जैसे अनलाडेन निगल के माध्यम से) लात मारने और चिल्लाने लगते हैं 21 वीं शताब्दी में भी? मैं अपने पुन: प्रयोज्य, पोर्टेबल पुस्तकालयों (एक-प्रयोग, फेंकने, स्क्रिप्ट और मामूली मॉड्यूल के विपरीत) में आरसी पर "भरोसा नहीं" के बारे में ओपी से सहमत हूं। –

+0

@ एसएलॉट: एलेक्स ने पहले ही आपके प्रश्न का उत्तर दिया है। संदर्भ गणना पर भरोसा नहीं करना चाहते हैं, यह एक और अच्छा कारण है कि पीआईपी परियोजना से बाहर आने वाला जेआईटी है। इसके पीछे के लोग आशावादी हैं कि यह सीपीथन की तुलना में वैकल्पिक गति अप प्रदान करने में सक्षम होंगे। – Arlaharen

उत्तर

13

लघु जवाब: नहीं

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

इसके अलावा, __del__ कहा जाता हो जाता है जब अजगर कचरा एकत्र करता है, और आप अजगर कचरा एकत्र करने, जिसका मतलब है तुम वैसे भी __del__ उपयोग नहीं कर सकते के लिए इंतजार नहीं करना चाहता था।

तो, __del__ का उपयोग न करें। इसके बजाय __enter__/__exit__ का उपयोग करें।

FYI करें: यहाँ एक गैर परिपत्र स्थिति का एक उदाहरण है, जहां नाशक बुलाया नहीं जा सके थे है:

class A(object): 
    def __init__(self): 
     print('Constructing A') 

    def __del__(self): 
     print('Destructing A') 

class B(object): 
    a = A() 

ठीक है, तो यह एक वर्ग विशेषता है। जाहिर है कि यह एक विशेष मामला है। लेकिन यह सिर्फ यह दिखाने के लिए चला जाता है कि __del__ कहलाता है कि यह सीधा नहीं है। मुझे पूरा यकीन है कि मैंने और गैर-परिपत्र स्थितियों को देखा है जहां __del__ नहीं कहा जाता है।

+0

मैंने एक साल पहले इसी तरह के एक प्रश्न पूछा था। अब तक, कोई भी वैध परिदृश्य नाम देने में सक्षम नहीं है जिसमें '__del__' विधि किसी भी उपयोग का होगा। जहां तक ​​मेरा संबंध है, विधि पहली जगह पाइथन में कभी नहीं होनी चाहिए। यह कुछ भी अच्छा नहीं है और लोगों को झूठी छाप देता है कि वे सफाई के लिए इसका इस्तेमाल कर सकते हैं। – antred

8

आवश्यक नहीं है। जब आपके पास चक्रीय संदर्भ होते हैं तो आपको समस्याएं आती हैं।

+0

+1 बहुत अच्छा लिंक – dfa

+1

दुर्भाग्यवश लेख से जुड़ा हुआ एक गलत निष्कर्ष निकाला गया है। '__del__' को कॉल करने की गारंटी नहीं है। बिलकुल। यह केवल चक्रीय संदर्भों के लिए नहीं है। इसके अलावा, यह कहता है ** "चक्रीय संदर्भ, हालांकि, अक्सर खराब डिजाइन का संकेत है" ** डब्ल्यूटीएफ? – nosklo

0

क्या आप वाकई चक्रीय संदर्भ में नहीं जाना होगा, तो वह रास्ते में __del__ का उपयोग कर रहे हैं ठीक है:: एली बेन्देर्स्क्य अपने ब्लॉग पोस्ट में इस समझाने का एक अच्छा काम करता है के रूप में जल्द क्योंकि संदर्भ गणना शून्य पर जाती है, सीपीथॉन वीएम उस विधि को कॉल करेगा और ऑब्जेक्ट को नष्ट कर देगा।

यदि आप चक्रीय संदर्भों का उपयोग करने की योजना बना रहे हैं - कृपया इसे बहुत अच्छी तरह से सोचें, और जांचें कि क्या कमजोर संदर्भ मदद कर सकते हैं; कई मामलों में, चक्रीय संदर्भ खराब डिजाइन का पहला लक्षण हैं।

यदि आपके ऑब्जेक्ट का उपयोग करने के तरीके पर कोई नियंत्रण नहीं है, तो __del__ का उपयोग सुरक्षित नहीं हो सकता है।

यदि आप जेपीथॉन या आयरनपीथन का उपयोग करने की योजना बना रहे हैं, तो __del__ अविश्वसनीय है, क्योंकि अंतिम ऑब्जेक्ट विनाश कचरा संग्रह में होगा, और ऐसा कुछ है जिसे आप नियंत्रित नहीं कर सकते।

कुल मिलाकर, मेरी राय में, __del__ आमतौर पर पूरी तरह से सुरक्षित और अच्छा है; हालांकि, कई स्थितियों में एक कदम वापस करना बेहतर हो सकता है, और एक अलग परिप्रेक्ष्य से समस्या को देखने का प्रयास करें; कोशिश/छोड़कर और संदर्भों के साथ एक अच्छा उपयोग एक और पायथनिक समाधान हो सकता है।

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