try-except 块:如果引发异常,则模拟 'else'

try-except block: analogue for 'else' if exception was raised

我有这样的代码:

try:
    return make_success_result()
except FirstException:
    handle_first_exception()
    return make_error_result()
except SecondException:
    handle_second_exception()
    return make_error_result()

我想知道有什么方法可以做到这一点:

try:
    # do something
except Error1:
    # do Error1 specific handling
except Error2:
    # do Error2 specific handling
else:
    # do this if there was no exception
????:
    # ALSO do this if there was ANY of the listed exceptions (e.g. some common error handling)

因此代码按以下顺序之一执行:

try > else > finally
try > except > ???? > finally

EDIT: my point here is that ???? block should execute right after ANY of the except blocks, meaning that it's an addition to error handling, not a substitution.

在这种情况下,我会做的是在出现异常时设置一个布尔值,如下所示:

got_exception = False
try:
    # do something
except Error1:
    # do Error1 specific handling
    got_exception = True
except Error2:
    # do Error2 specific handling
    got_exception = True
else:
    # If there was no exception
finally:
    if got_exception:
        # ALSO do this if there was ANY exception (e.g. some common error handling)

这应该符合您的需求,这是 IMO 将所有已呈现的解决方案组合成最易调试的最易读代码结构的最简洁方法。

是的,python 中的异常处理包括 elsefinally 子句。你可以这样做:

try:
    # do something
except Error1:
    # do Error1 specific handling
except Error2:
    # do Error2 specific handling
else:
    # do this if there was no exception
finally:
    # Do this in any case!

python docs 提到了这些块,尽管它没有显示您需要的完整示例。


编辑: 我看到您在一般情况下并没有专门要求清理。 Python 文档是这样说的:

The try statement has another optional clause which is intended to define clean-up actions that must be executed under all circumstances.

请注意 finally 将 运行 无论是否有异常。结合 else 块,你应该仍然可以做你想做的事。

你实际上可以这样做:

try:
    print 'try'
    # 1/0
    # {}[1]
    # {}.a
except AttributeError, KeyError:  # only handle these exceptions..
    try:
        raise                     # re-raise the exception so we can add a finally-clause executing iff there was an exception.
    except AttributeError:
        print 'attrerr'
        # raise ...               # any raises here will also execute 'common'
    except KeyError:
        print 'keyerror'
    finally:                      # update 0: you wanted the common code after the exceptions..
        print "common"

else:
    print 'no exception'

但这很可怕,我不建议你在没有大量评论说明原因的情况下这样做......

更新: 除了内部 try 块中有趣的异常外,您不需要捕获任何内容。代码已更新。

UPDATE2: 根据 OP 的说明,common 应该在抛出有趣的异常时执行。代码已更新。 @MattTaylor 的版本绝对是正确的选择;-)

您可以捕获所有错误并在错误处理代码中检查其类型,如下所示:

try:
    # do something
except Exception as e:
    if isinstance(e, Error1):
        # do Error1 specific handling
    elif isinstance(e, Error2):
        # do Error2 specific handling
    else:
        # do non-Error1/Error2 handling
    # ALSO do this if there was ANY exception (e.g. some common error handling)
else:
    # do this if there was no exception