किसी भी अपवाद को पकड़ने के बारे में


696

मैं एक ऐसा try/ exceptब्लॉक कैसे लिख सकता हूं जो सभी अपवादों को पकड़ता है?


4
ज्यादातर मामलों में, यदि आप किसी भी अपवाद को पकड़ने की कोशिश कर रहे हैं, तो आप गलत तरीके से कर रहे हैं। मेरा मतलब है कि आप बस अपने कोड में कुछ गलत कर सकते हैं और आपको इसके बारे में पता भी नहीं चलेगा। विशिष्ट अपवादों को पकड़ने के लिए यह एक अच्छा अभ्यास है।
vwvolodya

12
अधिक सटीक होने के लिए, सभी संभावित अपवादों को पकड़ना केवल एक समस्या है अगर वे चुपचाप पकड़े जाते हैं। यह सोचना कठिन है कि यह दृष्टिकोण कहां तक ​​उचित है, इसके अलावा जहां पकड़े गए त्रुटि संदेश मुद्रित होते हैं sys.stderrऔर संभवतः लॉग किए जाते हैं। यह पूरी तरह से मान्य और सामान्य अपवाद है।
इवगेनी सर्गेव

आप का प्रयास किया: try: whatever() except Exception as e: exp_capture() ?
चार्ली पार्कर

जवाबों:


564

आप कर सकते हैं लेकिन आप शायद नहीं करना चाहिए:

try:
    do_something()
except:
    print "Caught it!"

हालाँकि, यह भी अपवादों को पकड़ लेगा KeyboardInterruptऔर आप आमतौर पर ऐसा नहीं चाहते हैं, क्या आप? जब तक आप तुरंत अपवाद को फिर से नहीं बढ़ाते हैं - डॉक्स से निम्न उदाहरण देखें :

try:
    f = open('myfile.txt')
    s = f.readline()
    i = int(s.strip())
except IOError as (errno, strerror):
    print "I/O error({0}): {1}".format(errno, strerror)
except ValueError:
    print "Could not convert data to an integer."
except:
    print "Unexpected error:", sys.exc_info()[0]
    raise

30
संभावित वर्कअराउंड: effbot.org/zone/stupid-exception-keyboardinterrupt.htm
मिकेल

15
आपका अंतिम कथन सत्य नहीं है, आपको स्पष्ट रूप except Exception:से नंगे कहने की आवश्यकता है, सिवाय इसके कि आपके पास BaseException वालों को भी पकड़ा जाएगा।
पाइक्लर

7
आपको वास्तव में stderr पर प्रिंट करना चाहिए।
nyuszika7h

41
मैं बहुत दृढ़ता से इस कथन से असहमत हूं, "नहीं होना चाहिए।" आपको इसे संयम से करना चाहिए। ऐसे समय होते हैं जब आप थर्ड पार्टी लाइब्रेरियों (कभी-कभी डायनामिकली लोडेड !!) से निपटते हैं, जो अपवादों के साथ पूरी तरह से पागल हो गए हैं और उन सभी को ट्रैक करना एक बहुत ही दर्दनाक काम हो सकता है, और यदि आप बस एक को याद करते हैं, तो आपके पास एक बहुत है आपके सिस्टम में भारी दर्दनाक बग। यह कहा जा रहा है, आप के रूप में कई के रूप में नीचे ट्रैक करने के लिए अच्छा है और उन्हें उचित रूप से संभाल सकता है और फिर उन सभी के लिए एक बैकअप पकड़ है जिन्हें आप याद करते हैं।
ब्लेज़

26
जो मुझे अजीब लगता है वह यह है कि एक बतख टाइपिंग भाषा में जहां आप उदाहरण चर घोषित नहीं करते हैं, यह अचानक आपके अपवादों को टाइप न करने के बारे में बहुत चिंतित है। हम्म!
ब्लेज़

835

एक नंगे except:क्लॉज़ के अलावा (जैसा कि दूसरों ने कहा है कि आपको उपयोग नहीं करना चाहिए), आप बस पकड़ सकते हैं Exception:

import traceback
import logging

try:
    whatever()
except Exception as e:
    logging.error(traceback.format_exc())
    # Logs the error appropriately. 

आप आमतौर पर कभी भी अपने कोड के सबसे बाहरी स्तर पर ऐसा करने पर विचार करेंगे यदि उदाहरण के लिए आप समाप्त करने से पहले किसी भी अन्यथा अनुपलब्ध अपवाद को संभालना चाहते थे।

except Exceptionनंगे पर लाभ यह exceptहै कि कुछ अपवाद हैं जो इसे पकड़ नहीं सकते हैं, सबसे स्पष्ट रूप से KeyboardInterruptऔर SystemExit: यदि आपने उन्हें पकड़ा और निगल लिया तो आप किसी को भी अपनी स्क्रिप्ट से बाहर निकलने के लिए कठिन बना सकते हैं।


मेरे दिमाग में एक ही बात थी, लेकिन उनका नुकसान है, मान लें कि एक बार पकड़े जाने पर उनकी दो त्रुटियां हैं और आप को छोड़कर केवल आप कोशिश कर रहे ब्लॉक से बाहर निकल जाएंगे और आप दूसरी त्रुटि कभी नहीं जान पाएंगे। ।

6
किसी को भी आश्चर्य हो, मेरी अपेक्षा के विपरीत यह अभी भी गैर-अपवाद उपवर्गों को पकड़ लेगा जैसे कि चींटियों को, कम से कम अजगर 2.x में।
जोसेफ गार्विन

5
@ जोसेफगर्विन, यह गलत है, अर्थात यह "गैर-अपवाद" नहीं पकड़ेगा जो उपवर्ग नहीं है Exception। ध्यान दें कि intएक अपवाद के रूप में उठाना असंभव है, और ऐसा करने का प्रयास एक TypeErrorअपवाद को जन्म देता है, जो कि except Exceptionऐसे मामले में संलग्नक खंड द्वारा पकड़ा जाएगा । दूसरी ओर, एक पुरानी शैली के वर्ग को उठाया जा सकता है और एक "गैर-अपवाद" के रूप में अर्हता प्राप्त करता है जो उपवर्ग नहीं करता है Exception- यह एक नंगे खंड द्वारा पकड़ा जाएगा,except लेकिन एक खंड द्वारा नहींexcept Exception
योएल

4
@JosephGarvin इस ब्लॉग प्रविष्टि की जाँच करें: chris-lamb.co.uk/posts/no-one-expects-string-literal-exception मैं इस पर @ योएल के साथ हूं, आपके परीक्षण में सिर्फ नकाब लगाया गया हैTypeError
डंकन

2
@CharlieParker उन्हें पकड़ने के साथ कुछ भी गलत नहीं है अगर आप चाहते हैं, लेकिन आप ज्यादातर नहीं करते हैं। sys.exit()आमतौर पर कॉल करने का मतलब है कि आप एप्लिकेशन को समाप्त करने की उम्मीद करते हैं लेकिन यदि आप SystemExit को पकड़ते हैं तो यह नहीं होगा। इसी तरह अगर आप एक रनिंग स्क्रिप्ट पर कंट्रोल-सी मारते हैं (विंडोज़ पर Ctrl-break) तो आप प्रोग्राम को बंद करने की उम्मीद करते हैं, न कि त्रुटि को पकड़ने और चलते रहने की। लेकिन आप या तो इन दोनों को पकड़ सकते हैं यदि आप मौजूदा से पहले सफाई करना चाहते हैं।
डंकन

100

सामान्य अपवादों को संभालने के लिए आप ऐसा कर सकते हैं

try:
    a = 2/0
except Exception as e:
    print e.__doc__
    print e.message

8
यह सभी अपवादों को नहीं पकड़ सकता है, क्योंकि सभी अपवादों के लिए आधार वर्ग BaseException है और मैंने उत्पादन कोड का सामना किया है जो अपवाद वर्ग परिवार में नहीं है। इसके बारे में विवरण के लिए docs.python.org/3/library/… देखें ।
१६:०४ पर DDay

4
यह सभी अपवादों को नहीं पकड़ता है।
एंडी_अ And̷̷̷̷̷y

6
तकनीकी रूप से, इसे सभी गैर-प्रणाली-निकास अपवादों को पकड़ना चाहिए। डॉक्स से @DDay लिंक किया गया: " अपवाद BaseException: सभी बिल्ट-इन अपवादों के लिए बेस क्लास। इसका मतलब सीधे उपयोगकर्ता द्वारा परिभाषित कक्षाएं (इसके लिए, अपवाद का उपयोग करना) से विरासत में नहीं मिलता है।" जब तक आप उस कोड के साथ काम नहीं कर रहे हैं जो इसे अनदेखा करता है, या आपको सिस्टम-एक्ज़िटिंग अपवादों को पकड़ने की आवश्यकता है, ऊपर का उपयोग करने के लिए ठीक होना चाहिए।
पीटर कैसट्टा

@PeterCassetta जब कोई अपवाद छोड़कर सिस्टम को पकड़ना चाहेगा? यह प्रश्न में सामान्य धागा लगता है कि हम इन्हें पकड़ना नहीं चाहते हैं, लेकिन मुझे समझ नहीं आता कि क्यों। आमतौर पर क्यों नहीं?
चार्ली पार्कर 14

68

सभी संभावित अपवादों को पकड़ने के लिए, पकड़ना BaseException। यह अपवाद पदानुक्रम के शीर्ष पर है:

पायथन 3: https://docs.python.org/3.5/library/exception.html#exception-hierarchy

पायथन 2.7: https://docs.python.org/2.7/library/exception.html#exception-hierarchy

try:
    something()
except BaseException as error:
    print('An exception occurred: {}'.format(error))

लेकिन जैसा कि अन्य लोगों ने उल्लेख किया है, आपको आमतौर पर केवल विशिष्ट मामलों के लिए इसकी आवश्यकता नहीं होगी।


1
क्या Ctrl-C दबाने के बाद लंबे समय तक चलने वाली नौकरी की प्रगति को बचाना चाहते हैं?
BallpointBen

54

बहुत ही सरल उदाहरण, यहाँ पाए जाने वाले के समान:

http://docs.python.org/tutorial/errors.html#defining-clean-up-actions

यदि आप सभी अपवादों को पकड़ने का प्रयास कर रहे हैं, तो अपने सभी कोड "प्रयास:" कथन के भीतर रखें, 'प्रिंट' के स्थान पर एक क्रिया करना जो एक अपवाद को फेंक सकता है। ""।

try:
    print "Performing an action which may throw an exception."
except Exception, error:
    print "An exception was thrown!"
    print str(error)
else:
    print "Everything looks great!"
finally:
    print "Finally is called directly after executing the try statement whether an exception is thrown or not."

उपरोक्त उदाहरण में, आप इस क्रम में आउटपुट देखेंगे:

1) एक कार्रवाई करना जो एक अपवाद फेंक सकता है।

2) अंत में कोशिश बयान को निष्पादित करने के बाद सीधे कहा जाता है कि क्या एक अपवाद फेंक दिया गया है या नहीं।

3) "एक अपवाद फेंक दिया गया था!" या "सब कुछ बहुत अच्छा लग रहा है!" इस पर निर्भर करता है कि क्या एक अपवाद फेंका गया था।

उम्मीद है की यह मदद करेगा!


26

विशेष रूप से पायथन 3.0 और इसके बाद के संस्करण को करने के कई तरीके हैं

दृष्टिकोण १

यह सरल दृष्टिकोण है लेकिन अनुशंसित नहीं है क्योंकि आपको पता नहीं होगा कि वास्तव में कोड की कौन सी पंक्ति अपवाद को फेंक रही है:

def bad_method():
    try:
        sqrt = 0**-1
    except Exception as e:
        print(e)

bad_method()

दृष्टिकोण २

यह दृष्टिकोण अनुशंसित है क्योंकि यह प्रत्येक अपवाद के बारे में अधिक विवरण प्रदान करता है। उसमे समाविष्ट हैं:

  • आपके कोड के लिए लाइन नंबर
  • फ़ाइल का नाम
  • अधिक वर्बोज़ तरीके से वास्तविक त्रुटि

केवल दोष यह है कि आयात किए जाने की आवश्यकता है।

import traceback

def bad_method():
    try:
        sqrt = 0**-1
    except Exception:
        print(traceback.print_exc())

bad_method()

21

मुझे अभी परीक्षण के लिए इस छोटी सी चाल का पता चला है यदि पायथन 2.7 में अपवाद नाम। कभी-कभी मैंने कोड में विशिष्ट अपवादों को संभाला है, इसलिए मुझे यह देखने के लिए एक परीक्षण की आवश्यकता है कि क्या नाम संभाले गए अपवादों की सूची में है।

try:
    raise IndexError #as test error
except Exception as e:
    excepName = type(e).__name__ # returns the name of the exception

2
try:
    whatever()
except:
    # this will catch any exception or error

यह ध्यान देने योग्य है कि यह उचित पायथन कोडिंग नहीं है। यह उन कई त्रुटियों को भी पकड़ लेगा जिन्हें आप पकड़ना नहीं चाहते हैं।


बस कुछ अपवादों में उल्लिखित के अलावा सभी अपवादों का उपयोग न करें। आपको इस उद्देश्य के लिए BaseException का उपयोग करना होगा लेकिन जैसा कि आपने कहा, किसी को भी इस तरह के सभी अपवादों को नहीं पकड़ना चाहिए। मुझे लगता है कि यह एक शुरुआत के लिए ठीक है अगर लक्ष्य विकास के दौरान और अधिक दानेदार जोड़ना है, लेकिन मुझे नहीं लगता कि यह होगा ...
Pyglouthon
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.