我知道我可以做到:
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楼
如何在一行中捕获多个异常(块除外)
做这个:
try:
may_raise_specific_errors():
except (SpecificErrorOne, SpecificErrorTwo) as error:
handle(error) # might log or have some other default behavior...
由于使用了逗号将错误对象分配给名称的较旧语法,因此需要使用括号。 as
关键字用于分配。 您可以为错误对象使用任何名称,我个人更喜欢error
。
最佳实践
要以目前与Python向前兼容的方式做到这一点,您需要用逗号分隔Exceptions,并用括号将其包裹起来,以区别于早期的语法,后者通过遵循Exception类型来将异常实例分配给变量名称,以将其捕获为逗号。
这是一个简单用法的示例:
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中, except
块结束时, err
对象超出范围。
不推荐使用
您可能会看到用逗号分配错误的代码。 不赞成使用此用法,它是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
该try
, except
, pass
线路可以与单线处理抑制上下文管理器,可以在Python 3.4 :
from contextlib import suppress
with suppress(IDontLikeYouException, YouAreBeingMeanException):
do_something()
因此,当您要pass
某些异常时,请使用suppress
。
#2楼
一个
try
语句可能具有多个except子句,以指定不同异常的处理程序。 最多将执行一个处理程序。 处理程序仅处理在相应的try子句中发生的异常,而不处理同一try语句的其他处理程序中的异常。 exclude子句可以将多个异常命名为带括号的元组,例如:except (RuntimeError, TypeError, NameError): pass
请注意,必须在该元组周围加上括号,因为在现代Python中,除
ValueError, e:
之外ValueError, e:
是通常用作except ValueError as e:
之外的ValueError, e:
的语法(如下所述)。 为了向后兼容,仍旧支持旧语法。 这意味着,except RuntimeError, TypeError
不等同于except (RuntimeError, TypeError):
但不等同于except RuntimeError as
TypeError:
这不是您想要的。
#3楼
一种方法是..
try:
You do your operations here;
......................
except(Exception1[, Exception2[,...ExceptionN]]]):
If there is any exception from the given exception list,
then execute this block.
......................
else:
If there is no exception then execute this block.
而另一个方法是创建一个用来执行任务的执行方法except
块,并调用它通过所有的except
块你写的..
try:
You do your operations here;
......................
except Exception1:
functionname(parameterList)
except Exception2:
functionname(parameterList)
except Exception3:
functionname(parameterList)
else:
If there is no exception then execute this block.
def functionname( parameters ):
//your task..
return [expression]
我知道第二种方法并不是做到这一点的最佳方法,但我只是在说明一些实现此目的的方法。
#4楼
如果您经常使用大量异常,则可以预定义一个元组,因此您不必多次重新键入它们。
#This example code is a technique I use in a library that connects with websites to gather data
ConnectErrs = (URLError, SSLError, SocketTimeoutError, BadStatusLine, ConnectionResetError)
def connect(url, data):
#do connection and return some data
return(received_data)
def some_function(var_a, var_b, ...):
try: o = connect(url, data)
except ConnectErrs as e:
#do the recovery stuff
blah #do normal stuff you would do if no exception occurred
笔记:
同样,如果您还需要捕获除预定义元组中的异常以外的其他异常,则需要定义另一个except块。
如果您不能忍受全局变量,请在main()中定义它,并在需要的地方传递它...
#5楼
从Python文档 :
例如,except子句可以将多个异常命名为带括号的元组。
except (IDontLikeYouException, YouAreBeingMeanException) as e:
pass
或者,仅对于Python 2:
except (IDontLikeYouException, YouAreBeingMeanException), e:
pass
用逗号将变量与变量分开仍然可以在Python 2.6和2.7中使用,但是现在已弃用,并且在Python 3中不起作用。 现在您应该使用as
。