अपवादों को ठीक से कैसे अनदेखा करें


776

जब आप केवल एक अपवाद को छोड़कर प्रयास करना चाहते हैं, तो आप इसे पायथन में कैसे करते हैं?

क्या इसे करने का सही तरीका है?

try:
    shutil.rmtree(path)
except:
    pass

10
अजीब है कि किसी ने अब तक इसका उल्लेख नहीं किया (मैंने अपने जवाब में किया था), लेकिन इस विशिष्ट कार्य के लिए, आप बस कर सकते हैं shutil.rmtree(path, ignore_errors=True)। यह हालांकि अधिकांश कार्यों के लिए लागू नहीं होगा।
हारून हॉल

9
अपवादों को नजरअंदाज करने के बारे में सोचते समय महत्वपूर्ण पढ़ें: एक खराब प्रोग्रामिंग प्रथा को छोड़कर "पास: पास" क्यों है?
पोक

3
वास्तविक जीवन में ऐसा करने की कल्पना करें। कोशिश करें: get_cash ('$ 1000') को छोड़कर: पास # meh, यह शायद ठीक हो जाएगा
Grokodile

जवाबों:


1039
try:
    doSomething()
except: 
    pass

या

try:
    doSomething()
except Exception: 
    pass

अंतर यह है कि पहले वाला भी पकड़ लेगा KeyboardInterrupt, SystemExitऔर उस तरह का सामान, जो सीधे से प्राप्त होता है exceptions.BaseException, नहीं exceptions.Exception

विवरण के लिए दस्तावेज देखें:


4
ध्यान दें कि StopIteration और चेतावनी दोनों ही अपवाद के रूप में भी विरासत में मिली हैं। अपनी आवश्यकताओं के आधार पर, आप इसके बजाय StandardError से वारिस करना चाह सकते हैं।
बेन ब्लैंक

1
यह सच है, लेकिन अगर आप सावधान नहीं हैं, तो आप सूक्ष्म कीड़े में भाग सकते हैं (विशेषकर यदि आप StopIteration पर गुजरने के अलावा कुछ और कर रहे हैं)।
जेसन बेकर

17
-1, try: shuti.rmtree(...) except: passकिसी भी त्रुटी को बुरी तरह से दबा देगा (भले ही आप गलत shutilपरिणाम दें NameError) - बहुत कम से कमexcept OSError:
dbr

43
सूचनात्मक होते हुए भी यह उत्तर एक महत्वपूर्ण जानकारी याद आ रही है - आपको कभी भी इस तरह के अपवाद को नहीं पकड़ना चाहिए। इसके बजाय, आपको हमेशा केवल उन अपवादों को पकड़ने की कोशिश करनी चाहिए जिनकी आप परवाह करते हैं, अन्यथा आप बुरे सपने का शिकार करते समय बुरे सपने होंगे, आपके जेनेरिक द्वारा "सिवाय" को छिपाए। अधिक जानकारी के लिए dbr का उत्तर देखें। (मुझे पता है कि यह मूल प्रश्न नहीं था - लेकिन किसी को भी इसकी तलाश है बस आपका स्निपेट लेगा और इसका उपयोग करेगा)
johndodo

139

यह आम तौर पर केवल उन त्रुटियों को पकड़ने के लिए सर्वोत्तम-अभ्यास माना जाता है जिनमें आप रुचि रखते हैं। shutil.rmtreeसंभवतः इस मामले में OSError:

>>> shutil.rmtree("/fake/dir")
Traceback (most recent call last):
    [...]
OSError: [Errno 2] No such file or directory: '/fake/dir'

यदि आप चुपचाप उस त्रुटि को अनदेखा करना चाहते हैं, तो आप करेंगे:

try:
    shutil.rmtree(path)
except OSError:
    pass

क्यों? आप कहें (किसी तरह) गलती से एक स्ट्रिंग के बजाय एक पूर्णांक फ़ंक्शन को पास करें, जैसे:

shutil.rmtree(2)

यह त्रुटि देगा "TypeError: coercing to unicode: need string or बफर, int found" - आप शायद इसे अनदेखा नहीं करना चाहते हैं, जिसे डीबग करना मुश्किल हो सकता है।

यदि आप निश्चित रूप से सभी त्रुटियों को अनदेखा करना चाहते हैं, Exceptionतो नंगे except:बयान के बजाय पकड़ें । फिर, क्यों?

अपवाद निर्दिष्ट नहीं करना हर अपवाद को पकड़ता है, SystemExitउदाहरण सहित sys.exit()उपयोग के लिए अपवाद :

>>> try:
...     sys.exit(1)
... except:
...     pass
... 
>>>

इसकी तुलना निम्नलिखित से करें, जो सही ढंग से बाहर निकलता है:

>>> try:
...     sys.exit(1)
... except Exception:
...     pass
... 
shell:~$ 

यदि आप कभी बेहतर व्यवहार कोड लिखना चाहते हैं, तो OSErrorअपवाद विभिन्न त्रुटियों का प्रतिनिधित्व कर सकता है, लेकिन ऊपर दिए गए उदाहरण में हम केवल उपेक्षा करना चाहते हैं Errno 2, इसलिए हम और भी विशिष्ट हो सकते हैं:

import errno

try:
    shutil.rmtree(path)
except OSError as e:
    if e.errno != errno.ENOENT:
        # ignore "No such file or directory", but re-raise other errors
        raise

1
shutil.rmtreeसबसे अच्छा उदाहरण नहीं है, क्योंकि आप बस का प्रयोग करेंगे ignore_errors=Trueकि समारोह के लिए ..
विम

113

जब आप केवल अपवाद को संभालने के बिना ट्राई कैच करना चाहते हैं, तो आप इसे पायथन में कैसे करते हैं?

यह इस बात पर निर्भर करता है कि आपको "हैंडलिंग" से क्या मतलब है।

यदि आप बिना किसी कार्रवाई के इसे पकड़ने का मतलब है, तो आपके द्वारा पोस्ट किया गया कोड काम करेगा।

यदि आपका मतलब है कि आप बिना किसी अपवाद के स्टैक पर जाने से रोककर कार्रवाई करना चाहते हैं, तो आप कुछ इस तरह चाहते हैं:

try:
    do_something()
except:
    handle_exception()
    raise  #re-raise the exact same exception that was thrown

88

सबसे पहले मैं इस धागे से जैक ओ'कॉनर के उत्तर को उद्धृत करता हूं । संदर्भित धागा बंद हो गया, इसलिए मैं यहां लिखता हूं:

"पायथन 3.4 में ऐसा करने का एक नया तरीका है:"

from contextlib import suppress

with suppress(Exception):
    # your code

यहाँ यह है कि यह जोड़ा गया है: http://hg.python.org/cpython/rev/406b47c64480

और यहाँ लेखक रेमंड हेटिंगर, इस बारे में और अन्य सभी पायथन हॉटनेस के बारे में बात कर रहे हैं: https://youtu.be/OSGv2VnC0go?t=43m23s

मेरा इसके अलावा पायथन 2.7 समतुल्य है:

from contextlib import contextmanager

@contextmanager
def ignored(*exceptions):
    try:
        yield
    except exceptions:
        pass

फिर आप इसे Python 3.4 की तरह उपयोग करते हैं:

with ignored(Exception):
    # your code

55

संपूर्णता के लिए:

>>> def divide(x, y):
...     try:
...         result = x / y
...     except ZeroDivisionError:
...         print("division by zero!")
...     else:
...         print("result is", result)
...     finally:
...         print("executing finally clause")

यह भी ध्यान दें कि आप इस तरह के अपवाद को पकड़ सकते हैं:

>>> try:
...     this_fails()
... except ZeroDivisionError as err:
...     print("Handling run-time error:", err)

... और इस तरह से अपवाद फिर से बढ़ाएँ:

>>> try:
...     raise NameError('HiThere')
... except NameError:
...     print('An exception flew by!')
...     raise

... अजगर ट्यूटोरियल से उदाहरण ।


43

अपवादों को ठीक से कैसे अनदेखा करें?

इसे करने के कई तरीके हैं।

हालांकि, उदाहरण की पसंद का एक सरल समाधान है जो सामान्य मामले को कवर नहीं करता है।

उदाहरण के लिए विशिष्ट:

के बजाय

try:
    shutil.rmtree(path)
except:
    pass

यह करो:

shutil.rmtree(path, ignore_errors=True)

यह एक विशेष तर्क है shutil.rmtree। आप निम्न करके उस पर मदद देख सकते हैं, और आप देखेंगे कि यह त्रुटियों पर भी कार्यक्षमता के लिए अनुमति दे सकता है।

>>> import shutil
>>> help(shutil.rmtree)

चूंकि यह केवल उदाहरण के संकीर्ण मामले को कवर करता है, इसलिए मैं आगे प्रदर्शित करूँगा कि यदि उन कीवर्ड तर्क मौजूद नहीं थे, तो इसे कैसे संभालें।

सामान्य पहूंच

चूंकि ऊपर केवल उदाहरण के संकीर्ण मामले को कवर करता है, इसलिए मैं आगे प्रदर्शित करूँगा कि यदि उन कीवर्ड तर्क मौजूद नहीं थे, तो इसे कैसे संभालें।

पायथन 3.4 में नया:

आप suppressसंदर्भ प्रबंधक को आयात कर सकते हैं :

from contextlib import suppress

लेकिन केवल सबसे विशिष्ट अपवाद को दबाएं:

with suppress(FileNotFoundError):
    shutil.rmtree(path)

आप चुपचाप एक उपेक्षा करेंगे FileNotFoundError:

>>> with suppress(FileNotFoundError):
...     shutil.rmtree('bajkjbkdlsjfljsf')
... 
>>> 

से डॉक्स :

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

ध्यान दें कि suppressऔर FileNotFoundErrorकेवल पायथन 3 में उपलब्ध हैं।

यदि आप चाहते हैं कि आपका कोड पायथन 2 में भी काम करे, तो अगला भाग देखें:

अजगर 2 और 3:

जब आप केवल एक प्रयास करना चाहते हैं / बिना अपवाद को छोड़कर, आप इसे पायथन में कैसे करते हैं?

क्या इसे करने का सही तरीका है?

try :
    shutil.rmtree ( path )
except :
    pass

पायथन 2 संगत कोड के लिए, passयह एक कथन है कि यह एक नो-ऑप है। लेकिन जब आप एक नंगे कर except:, कर रही की तरह ही है except BaseException:जिसमें शामिल है GeneratorExit, KeyboardInterruptऔर SystemExit, और सामान्य रूप में, आप उन चीजों को पकड़ने के लिए नहीं करना चाहती।

वास्तव में, आपको अपवाद के रूप में विशिष्ट होना चाहिए जितना आप कर सकते हैं।

यहां पाइथन (2) अपवाद पदानुक्रम का हिस्सा है , और जैसा कि आप देख सकते हैं, यदि आप अधिक सामान्य अपवादों को पकड़ते हैं, तो आप उन समस्याओं को छिपा सकते हैं जिनकी आपको उम्मीद नहीं थी:

BaseException
 +-- SystemExit
 +-- KeyboardInterrupt
 +-- GeneratorExit
 +-- Exception
      +-- StopIteration
      +-- StandardError
      |    +-- BufferError
      |    +-- ArithmeticError
      |    |    +-- FloatingPointError
      |    |    +-- OverflowError
      |    |    +-- ZeroDivisionError
      |    +-- AssertionError
      |    +-- AttributeError
      |    +-- EnvironmentError
      |    |    +-- IOError
      |    |    +-- OSError
      |    |         +-- WindowsError (Windows)
      |    |         +-- VMSError (VMS)
      |    +-- EOFError
... and so on

आप शायद यहाँ एक OSError को पकड़ना चाहते हैं, और शायद कोई अपवाद नहीं है अगर कोई निर्देशिका नहीं है तो आप इसकी परवाह न करें।

हम उस विशिष्ट त्रुटि संख्या को errnoलाइब्रेरी से प्राप्त कर सकते हैं , और यदि हमारे पास ऐसा नहीं है तो:

import errno

try:
    shutil.rmtree(path)
except OSError as error:
    if error.errno == errno.ENOENT: # no such file or directory
        pass
    else: # we had an OSError we didn't expect, so reraise it
        raise 

ध्यान दें, एक नंगे उठान मूल अपवाद को उठाता है, जो शायद आप इस मामले में चाहते हैं। अधिक स्पष्ट रूप से लिखा गया है, क्योंकि हमें passअपवाद से निपटने में कोड के साथ स्पष्ट रूप से आवश्यकता नहीं है :

try:
    shutil.rmtree(path)
except OSError as error:
    if error.errno != errno.ENOENT: # no such file or directory
        raise 

11

जब आप केवल अपवाद को संभालने के बिना ट्राई कैच करना चाहते हैं, तो आप इसे पायथन में कैसे करते हैं?

इससे आपको यह पता लगाने में मदद मिलेगी कि अपवाद क्या है :( यानी अपवाद को हैंडल किए बिना पकड़ने की कोशिश करें और अपवाद को प्रिंट करें।)

import sys
try:
    doSomething()
except:
    print "Unexpected error:", sys.exc_info()[0]

10
try:
      doSomething()
except Exception: 
    pass
else:
      stuffDoneIf()
      TryClauseSucceeds()

FYI करें, अन्य खंड सभी अपवादों के बाद जा सकते हैं और केवल तभी चलाया जाएगा जब कोशिश में कोड अपवाद का कारण न बने।


1
अंत elseमें इस संदर्भ में एक अच्छी व्याख्या । और जोड़ने के लिए है कि finallyहोगा हमेशा किसी भी (या कोई अपवाद नहीं) होने लग जाते हैं।
not2qubit

5

मुझे कई कमांड्स में त्रुटियों को नजरअंदाज करने की जरूरत थी और चुदाई ने चाल चल दी

import fuckit

@fuckit
def helper():
    print('before')
    1/0
    print('after1')
    1/0
    print('after2')

helper()

+1 क्योंकि आपने निश्चित रूप से मेरा दिन बनाया है क्योंकि इस स्रोत कोड के अंदर आप कुछ बेहद उपयोगी चीजें सीख सकते हैं जैसे कि लाइव स्टैक को संशोधित करना
WBAR

3

पायथन में, हम अन्य भाषा के समान अपवादों को संभालते हैं, लेकिन अंतर कुछ सिंटैक्स अंतर है, उदाहरण के लिए,

try:
    #Your code in which exception can occur
except <here we can put in a particular exception name>:
    # We can call that exception here also, like ZeroDivisionError()
    # now your code
# We can put in a finally block also
finally:
    # Your code...

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.