协慌网

登录 贡献 社区

如何正确忽略异常

当您只想执行 try-except 但不处理异常时,如何在 Python 中进行呢?

以下是正确的方法吗?

try:
    shutil.rmtree(path)
except:
    pass

答案

try:
    doSomething()
except: 
    pass

要么

try:
    doSomething()
except Exception: 
    pass

不同之处在于,第一个也将捕获KeyboardInterruptSystemExit和类似的东西,它们直接从exceptions.BaseException而不是exceptions.Exception派生。
有关详细信息,请参见文档:

通常只捕获您感兴趣的错误被认为是最佳实践。在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 中做到这一点?

这取决于您所说的 “处理”。

如果您打算不采取任何措施就将其捕获,那么发布的代码将起作用。

如果您是想对异常采取行动而又不阻止异常上升,那么您需要这样的东西:

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