2009-10-01 6 views
86

क्या यह __init_ के भीतर अपवाद उठाने के लिए खराब रूप माना जाता है? यदि ऐसा है, तो कुछ वर्ग चर को किसी भी या गलत प्रकार के रूप में प्रारंभ करने पर त्रुटि को फेंकने की स्वीकार्य विधि क्या है?पायथन: क्या यह __init__ के भीतर अपवाद उठाने का बुरा फ़ॉर्म है?

+0

सी में, विनाशक में अपवाद बढ़ाने के लिए यह खराब रूप है, लेकिन कन्स्ट्रक्टर ठीक होना चाहिए। – Calyth

+4

@ उत्प्रेरक, आपका मतलब सी ++ है - उस मामले के लिए सी –

+2

... या अपवादों में कोई कन्स्ट्रक्टर या विनाशक नहीं हैं। –

उत्तर

111

__init__() के भीतर अपवाद बढ़ाना बिल्कुल ठीक है। एक कन्स्ट्रक्टर के भीतर त्रुटि स्थिति को इंगित करने का कोई और अच्छा तरीका नहीं है, और मानक लाइब्रेरी में कई सैकड़ों उदाहरण हैं जहां कोई ऑब्जेक्ट बनाना अपवाद बढ़ा सकता है।

त्रुटि वर्ग, निश्चित रूप से, आपके ऊपर है। ValueError सर्वोत्तम है यदि निर्माता को अमान्य पैरामीटर पारित किया गया हो।

+14

कन्स्ट्रक्टर में सबसे अधिक उपयोग किए गए अपवाद 'ValueError' और' TypeError' हैं। –

+0

बस यह इंगित करते हुए कि '__init__' कन्स्ट्रक्टर नहीं है, इसका इंटियालाइज़र है। आप लाइन को संपादित करना चाहते हैं * एक कन्स्ट्रक्टर के भीतर त्रुटि स्थिति इंगित करने के लिए कोई और अच्छा तरीका नहीं है .. * – Haris

3

मुझे लगता है कि यह अंतर्निहित ValueError अपवाद के लिए एकदम सही मामला है।

5

मानक पुस्तकालय का कहना है:

>>> f = file("notexisting.txt") 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
IOError: [Errno 2] No such file or directory: 'notexisting.txt' 

इसके अलावा, मैं वास्तव में किसी भी कारण है कि यह बुरा रूप में माना जाना चाहिए नहीं दिख रहा।

11

मुझे कोई कारण नहीं दिखता कि यह खराब रूप होना चाहिए।

इसके विपरीत, बातें अपवाद अच्छी तरह से कर लिए जाने जाते हैं, के रूप में लौटने त्रुटि कोड के लिए विरोध में से एक यह है कि त्रुटि कोड आमतौर पर कंस्ट्रक्टर्स से नहीं वापस किया जा सकता है। तो कम से कम सी ++ जैसी भाषाओं में, त्रुटियों को सिग्नल करने का एकमात्र तरीका अपवाद उठाना एकमात्र तरीका है।

2

मैं उपर्युक्त सभी के साथ सहमत हूं।

वास्तव में यह संकेत देने का कोई और तरीका नहीं है कि किसी अपवाद को बढ़ाने के अलावा किसी अन्य वस्तु के आरंभ में कुछ गलत हो गया है।

अधिकांश कार्यक्रम कक्षाओं में जहां कक्षा की स्थिति पूरी तरह से उस वर्ग के इनपुट पर निर्भर होती है, हम उम्मीद कर सकते हैं कि किसी प्रकार का ValueError या TypeError उठाया जाए।

साइड इफेक्ट्स (जैसे नेटवर्किंग या ग्राफिक्स करता है) के साथ कक्षाएं init में त्रुटि उत्पन्न कर सकती हैं (उदाहरण के लिए) नेटवर्क डिवाइस अनुपलब्ध है या कैनवास ऑब्जेक्ट को नहीं लिखा जा सकता है। यह मेरे लिए समझदार लगता है क्योंकि अक्सर आप जितनी जल्दी हो सके विफलता स्थितियों के बारे में जानना चाहते हैं।

18

यह सच है कि एक निर्माता में त्रुटि इंगित करने का एकमात्र उचित तरीका अपवाद उठा रहा है। यही कारण है कि सी ++ में और अन्य ऑब्जेक्ट उन्मुख भाषाओं में जिन्हें अपवाद सुरक्षा के साथ दिमाग में डिजाइन किया गया है, किसी ऑब्जेक्ट के निर्माता में अपवाद डाला गया है (जिसका अर्थ है कि ऑब्जेक्ट का प्रारंभिक अधूरा है) तो विनाशक को नहीं कहा जाता है। यह अक्सर पियथन जैसे स्क्रिप्टिंग भाषाओं में मामला नहीं है। उदाहरण के लिए, निम्न कोड एक AttributeError फेंकता है तो socket.connect() विफल रहता है:

class NetworkInterface: 
    def __init__(self, address) 
     self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
     self.socket.connect(address) 
     self.stream = self.socket.makefile() 

    def __del__(self) 
     self.stream.close() 
     self.socket.close() 

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

+0

यह उत्तर वास्तव में उपयोगी है। यह सिर्फ "हरे रंग की रोशनी" के बारे में नहीं बोल रहा है, लेकिन "विनाशक" के साथ एक उदाहरण का उल्लेख करता है। – lpapp

2

कुछ मामलों में इनिट से त्रुटियां बढ़ाना अपरिहार्य है, लेकिन इनिट में बहुत अधिक काम करना एक खराब शैली है। आपको फैक्ट्री या छद्म फैक्ट्री बनाने पर विचार करना चाहिए - एक साधारण क्लासमेड जो ऑब्जेक्ट सेट अप करता है।

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