我想知道在python中编写try
.. except
语句的最优雅方式是什么。假设我有这个代码:
with open(sys.argv[1]) as f:
for line in f:
try:
do_1(line)
except:
pass
try:
do_2(line)
except:
pass
try:
do_3(line)
except:
pass
...
...
写这个的最好方法是什么?我的行为是顺序的。但是,如果do_1
失败,我仍然希望执行do_2
。如果所有这些都在一个try
.. except
块中,那么如果do_1
失败,我将永远不会到达do_2
。这是正确的方法,还是我可以为所有except
行动设置一个d0_i
?
答案 0 :(得分:7)
将它写成循环非常简单:
for action in [do_1, do_2, do_3, ...]:
try:
action(line)
except AppropriateExceptionType:
pass
答案 1 :(得分:6)
我会将公共代码分解为您的try/except
语句。类似的东西:
def run_safely(f, *args):
try:
f(*args)
except SpecificException:
# handle appropriately here
pass
with open(sys.argv[1]) as f:
for line in f:
run_safely(do_1, line)
run_safely(do_2, line)
run_safely(do_3, line)
答案 2 :(得分:0)
基本上,您需要每个do_<Step>
函数在前一个finally
块内运行,如下所示:
try:
do_1(line)
except:
# Handle failure
pass
finally:
# Run regardless
try:
do_2(line)
except:
# Handle failure
finally:
# Run regardless
try:
do_3(line)
...
这通过finally
块将函数链接在一起。请注意,如果在任何步骤发生异常,则在开始下一步之前处理异常,无论是否生成异常,都保证运行该异常。
由于你的函数都具有相同的形状(使用相同数量和类型的参数),你可以将这个模式抽象为一个函数,如下面的tryChain
:
def tryChain(functions, *sharedArgs)
f = functions.pop()
try:
f(*sharedArgs)
finally:
tryChain(functions)
try:
tryChain([do_1, do_2, ...], line, arg2, ...)
except SpecificException:
# Handle exception here, which may be propagated from any of the actions
pass
请注意,在这种情况下,只有最后一个异常被抛回给调用者;其他人都是隐藏的。 (您也可以在tryChain
中处理异常,并在其中插入except
块;或者,您可以为每个步骤传入错误处理程序;或者从异常类型到适当的处理程序的映射,并且如果它们都不匹配则重新抛出错误 - 但此时,您实际上正在重新发明异常处理。)