在一行中捕获多个异常(块除外)

2022-09-05 00:43:37

我知道我可以做到:

try:
    # do something that may fail
except:
    # do this if ANYTHING goes wrong

我也可以这样做:

try:
    # do something that may fail
except IDontLikeYouException:
    # say please
except YouAreTooShortException:
    # stand on a ladder

但是,如果我想在两个不同的例外中做同样的事情,我现在能想到的最好的事情就是这样做:

try:
    # do something that may fail
except IDontLikeYouException:
    # say please
except YouAreBeingMeanException:
    # say please

有没有办法让我做这样的事情(因为在两个例外中要执行的操作是):say please

try:
    # do something that may fail
except IDontLikeYouException, YouAreBeingMeanException:
    # say please

现在这真的不起作用,因为它与以下语法相匹配:

try:
    # do something that may fail
except Exception, e:
    # say please

因此,我捕捉两个截然不同的异常的努力并没有完全实现。

有没有办法做到这一点?


答案 1

来自 Python 文档

一个 except 子句可以将多个异常命名为带括号的元组,例如

except (IDontLikeYouException, YouAreBeingMeanException) as e:
    pass

或者,仅适用于 Python 2:

except (IDontLikeYouException, YouAreBeingMeanException), e:
    pass

用逗号将异常与变量分开仍然适用于Python 2.6和2.7,但现在已被弃用,在Python 3中不起作用;现在你应该使用.as


答案 2

如何在一行中捕获多个异常(块除外)

请执行下列操作:

try:
    may_raise_specific_errors():
except (SpecificErrorOne, SpecificErrorTwo) as error:
    handle(error) # might log or have some other default behavior...

括号是必需的,因为旧语法使用逗号将错误对象分配给名称。关键字用于分配。你可以为错误对象使用任何名称,我个人更喜欢。aserror

最佳实践

若要以当前和向前与 Python 兼容的方式执行此操作,您需要用逗号分隔异常,并用括号括起来,以区别于早期的语法,这些语法通过遵循要用逗号捕获的 Exception 类型将异常实例分配给变量名称。

下面是一个简单用法的示例:

import sys

try:
    mainstuff()
except (KeyboardInterrupt, EOFError): # the parens are necessary
    sys.exit(0)

我只指定这些异常以避免隐藏错误,如果我遇到这些错误,我希望从中获得完整的堆栈跟踪。

这记录在这里:https://docs.python.org/tutorial/errors.html

您可以将异常分配给变量 ( 很常见,但是如果您有较长的异常处理,或者您的 IDE 仅突出显示大于该值的选择,则可能更喜欢更详细的变量,就像我一样。该实例具有一个 args 属性。下面是一个示例:e

import sys

try:
    mainstuff()
except (KeyboardInterrupt, EOFError) as err: 
    print(err)
    print(err.args)
    sys.exit(0)

请注意,在 Python 3 中,当块结束时,对象将超出范围。errexcept

荒废的

您可能会看到用逗号分配错误的代码。这种用法是Python 2.5及更早版本中唯一可用的形式,已被弃用,如果您希望您的代码在Python 3中向前兼容,则应更新语法以使用新形式:

import sys

try:
    mainstuff()
except (KeyboardInterrupt, EOFError), err: # don't do this in Python 2.6+
    print err
    print err.args
    sys.exit(0)

如果您在代码库中看到逗号名称分配,并且您使用的是 Python 2.5 或更高版本,请切换到新的操作方式,以便您的代码在升级时保持兼容。

上下文管理器suppress

接受的答案实际上是4行代码,最小值:

try:
    do_something()
except (IDontLikeYouException, YouAreBeingMeanException) as e:
    pass

、 、行可以使用抑制上下文管理器在一行中处理,这在 Python 3.4 中可用tryexceptpass

from contextlib import suppress

with suppress(IDontLikeYouException, YouAreBeingMeanException):
     do_something()

因此,当您想要在某些例外时,请使用 .passsuppress


推荐