python - ylabel - 如何正確地忽略異常?




python title position (7)

當你只想做一個嘗試 - 除了沒有處理異常之外,你怎麼在Python中做到這一點?

以下是正確的做法嗎?

try:
    shutil.rmtree(path)
except:
    pass

如何正確地忽略異常?

有幾種方法可以做到這一點。

然而,例子的選擇有一個簡單的解決方案,不包括一般情況。

具體到這個例子:

代替

try:
    shutil.rmtree(path)
except:
    pass

做這個:

shutil.rmtree(path, ignore_errors=True)

這是shutil.rmtree特有的一個參數。 通過執行以下操作,您可以看到它的幫助,並且您會發現它也可以允許錯誤的功能。

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

由於這只涵蓋了示例的狹義情況,因此如果這些關鍵字參數不存在,我將進一步演示如何處理此問題。

一般的做法

由於上述內容僅涵蓋範例的狹義範例,因此如果這些關鍵字參數不存在,我將進一步演示如何處理此問題。

Python 3.4新增功能:

您可以導入suppress上下文管理器:

from contextlib import suppress

但只能抑制最具體的例外情況:

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

你會默默地忽略FileNotFoundError

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

docs

和其他任何完全抑制異常的機制一樣,這個上下文管理器應該只用於覆蓋非常具體的錯誤,在那裡默默地繼續執行程序是正確的。

請注意, suppressFileNotFoundError僅在Python 3中可用。

如果你希望你的代碼在Python 2中工作,請參閱下一節:

Python 2&3:

當你只是想做一個嘗試/除非沒有處理異常,你如何在Python中做到這一點?

以下是正確的做法嗎?

try :
    shutil.rmtree ( path )
except :
    pass

對於Python 2兼容的代碼來說, pass是一個正確的方式來讓一個沒有操作的語句。 但是當你做一個except: ...... except: ,這與except BaseException:的操作相同except BaseException:它包括GeneratorExitKeyboardInterruptSystemExit ,並且通常你不想捕獲這些東西。

事實上,您應該盡可能具體地指定例外。

這是Python(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 

當你只想做一個try catch而不處理異常時,你如何在Python中做到這一點?

這取決於你的意思是“處理”。

如果你的意思是在沒有採取任何行動的情況下抓住它,你發布的代碼將會起作用。

如果你的意思是你想對異常採取行動而不會停止堆棧上的異常,那麼你需要這樣的東西:

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

在python中處理異常:如果您有一些可能引發異常的可疑代碼,您可以通過將可疑代碼放置在try:區塊中來維護您的程序。

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

在python中,我們處理類似於其他語言的異常,但差異在於某些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..

通常認為最好的做法是只捕獲你感興趣的錯誤。對於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:強制為Unicode:需要字符串或緩衝區,找到int” - 您可能不想忽略該錯誤,這可能很難調試。

如果您肯定要忽略所有錯誤,請捕獲Exception而不是純粹的except:語句。 同樣,為什麼?

不指定異常會捕獲每個異常,包括例如sys.exit()使用的SystemExit異常:

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

您也可以import errno並將if更改為if e.errno == errno.ENOENT:


首先,我從這個帖子引用傑克奧康納的回答。 被引用的線程被關閉了,所以我寫在這裡:

“Python 3.4中提供了一種新的方法:

from contextlib import suppress

with suppress(Exception):
    # your code

以下是添加它的提交: http://hg.python.org/cpython/rev/406b47c64480 : http://hg.python.org/cpython/rev/406b47c64480

下面是作者Raymond Hettinger談論這個以及各種其他Python熱點: https://youtu.be/OSGv2VnC0go?t=43m23s ://youtu.be/OSGv2VnC0go https://youtu.be/OSGv2VnC0go?t=43m23s t https://youtu.be/OSGv2VnC0go?t=43m23s 43m23s

我對此的補充是Python 2.7的等價物:

from contextlib import contextmanager

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

然後你就像在Python 3.4中一樣使用它:

with ignored(Exception):
    # your code







try-except