如何正确地忽略异常

问题描述 投票:671回答:11

当你只想做一个尝试,只是没有处理异常,你是怎么做到这在Python?

在下面的做的正确方法?

try:
    shutil.rmtree(path)
except:
    pass
python exception try-except
11个回答
971
投票
try:
  doSomething()
except: 
  pass

要么

try:
  doSomething()
except Exception: 
  pass

所不同的是,第一个也将赶上KeyboardInterruptSystemExit之类的东西,这是直接来源于exceptions.BaseException,不exceptions.Exception。 详细信息请参见文档:


3
投票

我需要忽略多个命令错误和fuckit的伎俩

import fuckit

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

helper()

-1
投票

简单地提高相关的异常,就像这样:

try:
     raise NameError('Joan')
 except NameError:
     print 'An exception just raised again by Joan!'
     raise

就如此容易。 :)

欲了解更多详细信息,请阅读本文档:https://docs.python.org/3.6/tutorial/errors.html


127
投票

它通常被认为是最佳的做法是只抓到你感兴趣的错误在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)

它会给错误“类型错误:强迫为Unicode:需要字符串或缓冲区,诠释发现” - 你可能不想忽略,这可能是难以调试。

如果你一定要忽略所有的错误,赶上Exception而不是裸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

你也可以import errno和改变ifif e.errno == errno.ENOENT:


109
投票

如果你只想做一个尝试捕捉不处理例外,你是怎么做到这一点在Python?

这取决于你的意思是什么“的处理。”

如果你的意思是抓住它没有采取任何行动,您发布的代码将工作。

如果你的意思是你想利用上的异常操作,而不从去向上堆栈停止异常,那么你想是这样的:

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

82
投票

首先,我引用杰克·奥康纳的回答this thread。引用的线程获得封闭,所以我写在这里:

“有一种新的方式来做到这一点在Python 3.4来了:

from contextlib import suppress

with suppress(Exception):
    # your code

这里的承诺是增加它:http://hg.python.org/cpython/rev/406b47c64480

而这里的作者,雷蒙德赫廷杰,说起这个和各种其他Python辣味:https://youtu.be/OSGv2VnC0go?t=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

54
投票

为了完整:

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

......从python tutorial

另外请注意,您可以捕捉这样的例外:

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

41
投票

How to properly ignore Exceptions?

有这样做的几种方法。

然而,示例的选择有一个简单的解决方案,它不覆盖的一般情况。

具体到实施例:

代替

try:
    shutil.rmtree(path)
except:
    pass

做这个:

shutil.rmtree(path, ignore_errors=True)

这是特定于shutil.rmtree参数。您可以通过执行以下看到它的帮助下,你会看到它也可以允许在错误的功能良好。

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

由于这仅覆盖了例如狭窄的情况下,我会进一步说明如何处理这一点,如果不存在这些关键字参数。

General approach

由于上述仅覆盖例如狭窄的情况下,我会进一步说明如何处理这一点,如果不存在这些关键字参数。

新的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工作为好,请参阅下一节:

蟒2和3:

当你只想做一个try /只是没有处理异常,你是怎么做到这在Python?

在下面的做的正确方法?

try :
    shutil.rmtree ( path )
except :
    pass

对于Python 2代码兼容,pass是有,这是一个无操作声明的正确方法。但是,当你做裸except:,这是一样的做except BaseException:包括GeneratorExitKeyboardInterruptSystemExit,并在一般情况下,你不想要赶上那些东西。

事实上,你应该在命名例外,你可以具体。

下面是Python的(2)exception hierarchy的一部分,你可以看到,如果你捕捉更多的一般例外,你可以隐藏你没有想到的问题:

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 

12
投票

如果你只想做一个尝试捕捉不处理例外,你是怎么做到这一点在Python?

这将帮助您打印的例外是什么:(即尽量不捕处理异常和打印除外)。

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

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

FYI else子句都可以异常之后去,如果在try代码不会导致异常才会运行。


5
投票

在Python中,我们处理类似其他语言的例外,但不同的是一些语法差异,例如,

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...
© www.soinside.com 2019 - 2024. All rights reserved.