写多个try而不是python

时间:2015-12-28 22:02:45

标签: python try-catch

我想知道在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

3 个答案:

答案 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块;或者,您可以为每个步骤传入错误处理程序;或者从异常类型到适当的处理程序的映射,并且如果它们都不匹配则重新抛出错误 - 但此时,您实际上正在重新发明异常处理。)