जब PyCharm IDE का उपयोग except:
बिना अपवाद के प्रकार का उपयोग करता है, तो IDE से एक अनुस्मारक ट्रिगर होता है जो यह अपवाद खंड है Too broad
।
क्या मुझे इस सलाह को अनदेखा करना चाहिए? या यह हमेशा अपवाद प्रकार विशिष्ट करने के लिए पायथोनिक है?
जब PyCharm IDE का उपयोग except:
बिना अपवाद के प्रकार का उपयोग करता है, तो IDE से एक अनुस्मारक ट्रिगर होता है जो यह अपवाद खंड है Too broad
।
क्या मुझे इस सलाह को अनदेखा करना चाहिए? या यह हमेशा अपवाद प्रकार विशिष्ट करने के लिए पायथोनिक है?
जवाबों:
एक स्पष्ट अपवाद प्रकार निर्दिष्ट करना लगभग हमेशा बेहतर होता है। यदि आप एक नग्न except:
क्लॉज का उपयोग करते हैं , तो आप उन अपवादों को छोड़ सकते हैं, जिन्हें आप पकड़ने की अपेक्षा करते हैं - यह बग को छिपा सकते हैं या प्रोग्राम को डिबग करने के लिए कठिन बना सकते हैं जब वे ऐसा नहीं कर रहे हैं जो आप अपेक्षा करते हैं।
उदाहरण के लिए, यदि आप किसी डेटाबेस में एक पंक्ति सम्मिलित कर रहे हैं, तो आप एक अपवाद को पकड़ना चाहते हैं जो इंगित करता है कि पंक्ति पहले से मौजूद है, इसलिए आप एक अद्यतन कर सकते हैं।
try:
insert(connection, data)
except:
update(connection, data)
यदि आप एक नंगे निर्दिष्ट करते हैं except:
, तो आप एक सॉकेट त्रुटि भी दर्शाएंगे जो यह दर्शाता है कि डेटाबेस सर्वर गिर गया है। यह केवल अपवादों को पकड़ने के लिए सबसे अच्छा है जिसे आप जानते हैं कि कैसे संभालना है - यह अपवाद के बिंदु पर विफल रहने के लिए अक्सर कार्यक्रम के लिए बेहतर है कि जारी रखें लेकिन अजीब अप्रत्याशित तरीके से व्यवहार करें।
एक मामला जहां आप नंगे except:
का उपयोग करना चाहते हैं , वह एक प्रोग्राम के शीर्ष-स्तर पर है जिसे आपको नेटवर्क सर्वर की तरह हमेशा चलाने की आवश्यकता है। लेकिन फिर, आपको अपवादों को लॉग करने के लिए बहुत सावधान रहने की आवश्यकता है, अन्यथा यह गलत नहीं है कि क्या गलत हो रहा है। मूल रूप से, ऐसा करने वाले कार्यक्रम में केवल एक ही स्थान पर होना चाहिए।
इस सब के लिए एक कोरोलरी यह है कि आपका कोड कभी नहीं करना चाहिए raise Exception('some message')
क्योंकि यह क्लाइंट कोड को उपयोग करने के लिए मजबूर करता है except:
(या except Exception:
जो लगभग उतना ही बुरा है)। आपको उस समस्या के अपवाद को परिभाषित करना चाहिए जिसे आप संकेत करना चाहते हैं (शायद कुछ अंतर्निहित अपवाद जैसे ValueError
या उपवर्ग से विरासत में मिला है TypeError
)। या आपको एक विशिष्ट अंतर्निहित अपवाद उठाना चाहिए। यह आपके कोड के उपयोगकर्ताओं को केवल उन अपवादों को पकड़ने में सावधान रहने में सक्षम बनाता है जिन्हें वे संभालना चाहते हैं।
except:
यह भी पकड़ता है (कई अन्य चीजों के बीच) NameError
और AttributeError
, इसलिए यदि आप try
ब्लॉक में किसी चीज़ को मिस करते हैं (जैसे कि आपका "इंसर्ट" फ़ंक्शन वास्तव में कहा जाता है, insert_one
क्योंकि किसी ने स्थिरता को उतना महत्व नहीं दिया है), जितना उन्हें चाहिए हमेशा चुपचाप करने की कोशिश करता है update()
।
main()
)?
except Exception:
पकड़ लेंगे NameError
और AttributeError
भी। जो चीज नंगी except:
होती है वह इतनी खराब होती है कि वह ऐसे सामान को पकड़ लेती है जिसका कोई व्यवसाय नहीं हो रहा है, उदाहरण के लिए SystemExit
(जब आप कॉल करते हैं exit
या उठाया जाता है sys.exit
, और अब आपने एक इच्छित निकास को रोका है) और KeyboardInterrupt
(फिर, यदि उपयोगकर्ता हिट करता है Ctrl-C
, तो आप शायद नहीं चाहते हैं बस उन्हें चलाने के लिए)। केवल बाद वाला किसी भी वास्तविक अर्थ को पकड़ने के लिए बनाता है, और इसे स्पष्ट रूप से पकड़ा जाना चाहिए। कम से कम except Exception:
उन दोनों को सामान्य रूप से प्रचारित करने देता है।
आपको उस सलाह की अनदेखी नहीं करनी चाहिए जो दुभाषिया आपको देता है।
से पीईपी-8 अजगर के लिए स्टाइल गाइड:
अपवादों को पकड़ते समय, किसी अपवाद को छोड़कर जब भी संभव हो, विशिष्ट अपवादों का उल्लेख करें: खंड।
उदाहरण के लिए, उपयोग करें:
try:
import platform_specific_module
except ImportError:
platform_specific_module = None
एक नंगे को छोड़कर: क्लॉज़ सिस्टमएक्सिट और कीबोर्डइंटरप्ट अपवादों को पकड़ लेगा, जिससे कंट्रोल-सी के साथ एक कार्यक्रम को बाधित करना मुश्किल हो जाएगा, और अन्य समस्याओं का सामना करना पड़ सकता है। यदि आप सभी अपवादों को पकड़ना चाहते हैं जो प्रोग्राम की त्रुटियों को इंगित करते हैं, तो अपवाद को छोड़कर उपयोग करें: (नंगे को छोड़कर, बेसएक्स अपवाद को छोड़कर :)।
अंगूठे का एक अच्छा नियम दो मामलों को छोड़कर 'नंगे' के उपयोग को सीमित करना है:
यदि अपवाद हैंडलर ट्रेसबैक को प्रिंट या लॉग कर रहा होगा; कम से कम उपयोगकर्ता को पता चल जाएगा कि कोई त्रुटि हुई है। यदि कोड को कुछ सफाई कार्य करने की आवश्यकता होती है, लेकिन फिर अपवाद को ऊपर की ओर फैलाने देता है। कोशिश करें ... आखिरकार इस मामले को संभालने का एक बेहतर तरीका हो सकता है।
यह पायथन के लिए विशिष्ट नहीं है।
अपवाद के पूरे बिंदु समस्या से निपटने के लिए है जहां यह संभव था।
तो आप कोड रखते हैं जो असाधारण cirumstances में समस्या को हल कर सकते हैं और एक दूसरे के लिए "अगला" संकल्प।
बात यह है कि आप उन सभी अपवादों को नहीं जान सकते जो कोड के एक टुकड़े द्वारा फेंके जा सकते हैं। आप सभी यह जान सकते हैं कि यदि यह एक कहावत है कि एक फ़ाइल अपवाद नहीं मिली, तो आप इसे फँसा सकते हैं और उपयोगकर्ता को उस कार्य को करने या रद्द करने के लिए प्रेरित कर सकते हैं।
अगर आप ट्रायल कैच राउंड लगाते हैं, तो इससे कोई फर्क नहीं पड़ता कि आपकी फाइल रूटीन में क्या समस्या थी (केवल रीड, परमिशन, यूएसी, वास्तव में एक पीडीएफ़ इत्यादि नहीं), हर एक आपकी फ़ाइल में ड्रॉप हो जाएगा जो कैच नहीं मिला, और आपका उपयोगकर्ता चिल्ला रहा है "लेकिन यह वहाँ है, यह कोड बकवास है"
अब कुछ ऐसे हालात हैं जहाँ आप सब कुछ झेल सकते हैं, लेकिन उन्हें सचेत रूप से चुना जाना चाहिए।
वे कुछ स्थानीय क्रियाओं (जैसे किसी संसाधन को बनाना या लॉक करना, उदाहरण के लिए लिखने के लिए डिस्क पर एक फ़ाइल खोलना) में पकड़ लेते हैं, फिर आप अपवाद को फिर से फेंकते हैं, जिससे उच्च स्तर पर निपटा जा सकता है)
दूसरी बात यह है कि आप यह नहीं सोचते कि यह गलत क्यों हुआ। उदाहरण के लिए मुद्रण। आपके पास पूरे दौर में एक पकड़ हो सकती है, यह कहने के लिए कि आपके प्रिंटर के साथ कुछ समस्या है, कृपया इसे सुलझाएं, और इसके कारण एप्लिकेशन को न मारें। ओना समान व्यर्थ यदि आपके कोड ने किसी प्रकार के शेड्यूल का उपयोग करके अलग-अलग कार्यों की एक श्रृंखला को निष्पादित किया है, तो आप चाहते हैं कि पूरी चीज मर जाएगी, क्योंकि कार्यों में से एक विफल हो गया।
नोट यदि आप ऊपर करते हैं, तो मैं कुछ प्रकार के अपवाद लॉगिंग की अनुशंसा नहीं कर सकता, उदाहरण के लिए, लॉग एंड को पकड़ने की कोशिश करें, अत्यधिक पर्याप्त।
आप इसके साथ कंट्रोल-सी भी पकड़ लेंगे, इसलिए इसे तब तक न करें जब तक आप इसे फिर से "फेंक" न दें। हालांकि, उस स्थिति में आपको "अंत में" का उपयोग करना चाहिए।
हमेशा की तरह, अपवाद के प्रकार का उल्लेख वहाँ कई प्रकार आप पकड़ नहीं करना चाहती, की तरह हैं SyntaxError
, KeyboardInterrupt
, MemoryError
आदि
except Exception:
उपरोक्त प्रकारों से बचने का उपयोग करने से जिन्हें हम पकड़ना नहीं चाहते हैं?
except Exception
ठीक है।
except Exception
कैच SyntaxError
और MemoryError
क्योंकि यह उनका बेस क्लास है। KeyboardInterrupt
, SystemExit
(द्वारा उठाए गए sys.exit()
) पकड़े नहीं गए हैं (वे तत्काल आधारभूत उपवर्ग हैं)
यहां वे स्थान हैं जहां मैं बिना किसी प्रकार को छोड़कर उपयोग करता हूं
अनियंत्रित अपवादों के लिए मेरे कोड में यह मुख्य उपयोग है
मैं हमेशा इसे जोड़ता हूं, ताकि उत्पादन कोड स्टैकट्रैक्स को फैल न सके
मेरे पास इसे करने के दो तरीके हैं:
मैं इसे इस तरह से पसंद करता हूं, मुझे यह पता लगाना आसान है कि किन अपवादों को उचित रूप से पकड़ा जाना चाहिए: निचले स्तर के अपवाद को उच्च स्तर से लॉग किए जाने पर समस्या को "बेहतर" देखता हूं।
कुछ सहकर्मी इस तरह से पसंद करते हैं, क्योंकि यह निचले स्तर के कार्यों में निचले स्तर के अपवादों को रखता है, जहां वे "संबंधित" हैं।