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

2024-03-19 03:22:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我知道我能做到:

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

所以,我捕捉这两个不同的异常的努力并没有完全实现。

有办法吗?


Tags: ifthatthisdosomethingmayfailsay
3条回答

来自Python Documentation

An except clause may name multiple exceptions as a parenthesized tuple, for example

except (IDontLikeYouException, YouAreBeingMeanException) as e:
    pass

或者,仅对于Python 2:

except (IDontLikeYouException, YouAreBeingMeanException), e:
    pass

在Python2.6和2.7中,用逗号将异常与变量分隔仍然有效,但现在已被弃用,在Python3中不起作用;现在应该使用as

来自Python documentation -> 8.3 Handling Exceptions

A try statement may have more than one except clause, to specify handlers for different exceptions. At most one handler will be executed. Handlers only handle exceptions that occur in the corresponding try clause, not in other handlers of the same try statement. An except clause may name multiple exceptions as a parenthesized tuple, for example:

except (RuntimeError, TypeError, NameError):
    pass

Note that the parentheses around this tuple are required, because except ValueError, e: was the syntax used for what is normally written as except ValueError as e: in modern Python (described below). The old syntax is still supported for backwards compatibility. This means except RuntimeError, TypeError is not equivalent to except (RuntimeError, TypeError): but to except RuntimeError asTypeError: which is not what you want.

How do I catch multiple exceptions in one line (except block)

执行以下操作:

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

括号是必需的,因为较旧的语法使用逗号将错误对象指定给名称。as关键字用于赋值。您可以为错误对象使用任何名称,我个人更喜欢error

最佳实践

要以与Python当前和正向兼容的方式执行此操作,您需要用逗号分隔异常,并用括号将其括起来,以区别于以前的语法,后者通过跟随要用逗号捕获的异常类型将异常实例分配给变量名。

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

import sys

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

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

这里有文档:https://docs.python.org/tutorial/errors.html

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

import sys

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

注意,在Python 3中,err对象在结束except块时超出了范围。

不赞成

您可能会看到用逗号指定错误的代码。这种用法是Python2.5和更早版本中唯一可用的形式,已被弃用,如果希望代码在Python3中向前兼容,则应更新语法以使用新形式:

import sys

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

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

上下文管理器

公认的答案实际上是4行代码,最少:

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

可以用suppress context manager, available in Python 3.4在一行中处理tryexceptpass行:

from contextlib import suppress

with suppress(IDontLikeYouException, YouAreBeingMeanException):
     do_something()

因此,当您想对某些异常使用pass时,请使用suppress

相关问题 更多 >