在一行中捕获多个exception(块除外)
我知道我可以这样做:
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
所以,我的努力来抓住两个明显的例外并不完全是通过。
有没有办法做到这一点?
来自Python文档 :
例如,except子句可以将多个exception命名为带括号的元组
except (IDontLikeYouException, YouAreBeingMeanException) as e: pass
用逗号分隔variables的exception仍然可以在Python 2.6和2.7中使用,但现在已经被弃用,并且在Python 3中不起作用。 现在你应该使用as
。
如何在一行中捕获多个exception(块除外)
做这个:
try: may_raise_specific_errors(): except (SpecificErrorOne, SpecificErrorTwo) as error: handle(error) # might log or have some other default behavior...
由于使用逗号将错误对象分配给名称的较旧语法,所以需要括号。 as
关键字用于分配。 您可以使用任何名称的错误对象,我个人比较喜欢error
。
最佳实践
要以与Python兼容的方式进行操作,需要用逗号分隔这些exception,并用圆括号将它们包装起来,以区别于之前的语法,将exception实例指定为一个variables名,逗号。
下面是一个简单的用法示例:我正在使用交互式命令行PythonTrainer程序封装main
的KeyboardInterrupt和EOFError,以便用户可以使用Ctrl + D或Ctrl + C :
try: mainstuff() except (KeyboardInterrupt, EOFError): # the parens are necessary for Python 3 quit(0)
我只指定这些例外,以避免隐藏错误,如果我遇到,我期望从完整的堆栈跟踪。
这是在这里logging: https : //docs.python.org/tutorial/errors.html
你可以把这个exception分配给一个variables,( e
是常见的,但是如果你有很长的exception处理,你可能更喜欢一个更详细的variables,或者你的IDE只突出显示大于这个值的select)。这个实例有一个args属性。 这里是一个例子:
try: mainstuff() except (KeyboardInterrupt, EOFError) as err: print(err) print(err.args) quit(0)
请注意,在Python 3中,当except
块结束时, err
对象超出范围。
弃用
您可能会看到用逗号分配错误的代码。 这种用法是Python 2.5及更早版本中唯一可用的forms,不推荐使用,如果您希望代码在Python 3中向前兼容,则应更新语法以使用新forms:
try: mainstuff() except (KeyboardInterrupt, EOFError), err: # don't do this in Python 2.6+ print err print err.args quit(0)
如果在代码库中看到逗号分配,并且使用的是Python 2.5或更高版本,请切换到新的方式,以便升级时代码保持兼容。
对于Python 2.5及更早版本,正确的语法是:
except (IDontLikeYouException, YouAreBeingMeanException), e: print e
其中e
是Exception实例。
从Python文档 – > 8.3处理exception :
try
语句可能有多个except子句,为不同的exception指定处理程序。 最多只有一个处理程序将被执行。 处理程序只处理发生在相应try子句中的exception,而不处理相同try语句的其他处理程序。 except子句可以将多个exception命名为括号化的元组,例如:except (RuntimeError, TypeError, NameError): pass
请注意,此元组周围的圆括号是必需的,因为除了
ValueError, e:
外ValueError, e:
是用于except ValueError as e:
通常以书面forms使用的语法except ValueError as e:
现代Python(如下所述)中的except ValueError as e:
旧的语法仍然支持向后兼容性。 这意味着except RuntimeError, TypeError
不等于except (RuntimeError, TypeError):
但是将except RuntimeError as
TypeError:
except RuntimeError as
TypeError:
这不是你想要的。
如果你经常使用大量的exception,你可以预先定义一个元组,所以你不必多次重新input。
#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
笔记:
-
如果您还需要捕获除预定义元组之外的其他exception,则需要定义另一个除了块的exception。
-
如果你不能容忍一个全局variables,在main()中定义它,并在需要的地方传递它。
其中一个方法是…
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.
另一种方法是创build方法,执行except
块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]
我知道第二个不是做这件事的最好方法,但是我只是展示了一些做这件事情的方法。
- 为什么在.NET中检查exception?
- Android,ListView IllegalStateException:“适配器的内容已经改变,但ListView没有收到通知”
- IllegalStateException的用途是什么?
- 从exception对象中提取回溯信息
- IntelliJ中是否有“Break on Exception”?
- 在Scala中抛出exception,什么是“官方规则”
- 如果没有人调用interrupt(),可以忽略InterruptedException吗?
- java.rmi.NoSuchObjectException:表中没有这样的对象
- devise模式:exception/error handling