很多时候我发现自己写的东西看起来像这样:
try:
procedure_a()
except WrongProcedureError:
try:
procedure_b()
except WrongProcedureError:
try:
procedure_c()
except WrongProcedureError:
give_up()
这很可怕。是否有更优雅的方式来实现这种“尝试直到一个不例外”的逻辑?看起来这种事情会出现很多;我希望有一些语言功能,我不知道这是为这个确切的东西设计的。
答案 0 :(得分:22)
您可以使用for/else
构造:
for proc in [procedure_a, procedure_b, procedure_c]:
try:
proc()
except WrongProcedureError:
continue
else:
break
else:
give_up()
else
循环的for
子句仅在控件自然脱离for子句的底部时触发。如果您break
出局(如果三个程序中的任何一个没有抛出异常,那么它就不会被触发)。
答案 1 :(得分:5)
循环程序。将循环包装成一个函数。在成功的情况下过早地从函数返回:
def try_all():
for procedure in [procedure_a, procedure_b, procedure_c]:
try:
procedure()
return
except WrongProcedureError:
continue
give_up()
答案 2 :(得分:3)
实际上你的方法并没有错。它使用普通语言功能并传达其信息非常清晰。
其他方法也有效,但理解起来有些复杂,可能只有在你想要检查的功能很多(不仅仅是3个)时才会更好。在那种情况下,我实际上会创建一个函数来隐藏这种复杂性。
import itertools
from contextlib import suppress
def call_functions(funcs, give_up_func):
for func in itertools.chain(funcs, [give_up_func]):
with suppress(WrongProcedureError):
func()
return # only reached when func does not raise WrongProcedureError.
假设give_up_func
不会引发异常而suppress
需要python 3(我认为3.4)。
但是,实际需要时,代码中可能存在根本错误。这似乎是某种“后备”操作,可能应该使用子类或其他参数或策略/工厂而不是嵌套的try
和except
来解决。