python - अपवादों को सही तरीके से अनदेखा कैसे करें?




exception exception-handling (7)

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

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

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

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

के बजाय

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')
... 
>>> 

docs :

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

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

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

पायथन 2 और 3:

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

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

try :
    shutil.rmtree ( path )
except :
    pass

पायथन 2 संगत कोड के लिए, pass एक ऐसा बयान देने का सही तरीका है जो नो-ऑप है। लेकिन जब आप एक नंगे except: except BaseException: ऐसा करने जैसा ही है except BaseException: जिसमें except BaseException: , KeyboardInterrupt SystemExit और 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

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

हम 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 

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

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

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

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

try:
    shutil.rmtree(path)
except:
    pass

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

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

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

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

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

इसे आम तौर पर आपकी shutil.rmtree त्रुटियों को पकड़ने के लिए सर्वोत्तम अभ्यास माना जाता है। 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: स्ट्रिंग या बफर की आवश्यकता है, int पाया" - आप शायद इसे अनदेखा नहीं करना चाहते हैं, जो डीबग करना मुश्किल हो सकता है।

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

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

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

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

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

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

try:
    shutil.rmtree(path)
except OSError, e:
    if e.errno == 2:
        # suppress "No such file or directory" error
        pass
    else:
        # reraise the exception, as it's an unexpected error
        raise

आप if e.errno == errno.ENOENT: import errno भी कर सकते हैं और if e.errno == errno.ENOENT: को बदल सकते हैं if if e.errno == errno.ENOENT:


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

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

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

"पाइथन 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

फिर आप इसे पायथन 3.4 में उपयोग करते हैं:

with ignored(Exception):
    # your code

पायथन में अपवाद को संभालना: यदि आपके पास कुछ संदिग्ध कोड है जो अपवाद बढ़ा सकता है, तो आप संदिग्ध कोड को एक प्रयास में डालकर अपने प्रोग्राम की रक्षा कर सकते हैं: ब्लॉक।

try:
    # your statements .............
except ExceptionI:
    # your statments.............
except ExceptionII:
    # your statments..............
else:
   # your statments

try:
  doSomething()
except: 
  pass

या

try:
  doSomething()
except Exception: 
  pass

अंतर यह है कि पहला व्यक्ति KeyboardInterrupt SystemExit , SystemExit और उस तरह की चीजें भी पकड़ SystemExit , जो सीधे exceptions.BaseException से व्युत्पन्न होते हैं। SystemExit exceptions.BaseException , exceptions.Exception नहीं। exceptions.Exception
विवरण के लिए दस्तावेज़ीकरण देखें:





try-except