异常处理块的正确范围

Correct extent of the exception handling block

假设我们有以下代码:

print("...")
might_throw_type_error()
print("...")
might_throw_index_error()

如果我们想处理那些函数可能出现的异常,首选方法是什么:


完全拆分 "business" 代码和错误处理

try:
    print("...")
    might_throw_type_error()
    print("...")
    might_throw_index_error()
except IndexError:
    # index error handling logic
    raise
except TypeError:
    # index error handling logic
    raise

逻辑和错误处理的拆分,但尝试从可能引发的第一个语句开始

print("...")
try:
    might_throw_type_error()
    print("...")
    might_throw_index_error()
except IndexError:
    # index error handling logic
    raise
except TypeError:
    # index error handling logic
    raise

异常处理应该只包装我们期望引发的语句

print("...")
try:
    might_throw_type_error()
except TypeError:
    # index error handling logic
    raise
print("...")
try:
    might_throw_index_error()
except IndexError:
    # index error handling logic
    raise

请注意,如果我们捕获异常,我们不想继续

这绝对取决于你到底想达到什么目的 - 考虑一下你是否会使用 #1 方法第一个 might_throw_index_error 错误,下面的 print 和第二个 might_throw_index_error 永远不会被执行 .

另一方面,最后一个保证至少第二个 print 会一直开火。

这些方法中的每一种都很好,但这取决于您希望如何处理您的应用程序流程。

创建一个 装饰器 并将该装饰器添加到您的每个函数定义中。检查 A guide to Python's function decorators 了解详细信息。例如,你的装饰器应该是这样的:

def wrap_error(func):
    def func_wrapper(*args, **kwargs):
        try:
           return func(*args, **kwargs)
        except ValueError:
           # Some logic here
        except IndexError:
           # some logic here
    return func_wrapper

现在用你的函数定义添加这个装饰器:

@wrap_error
def function1():
    some code

现在您可以简单地调用该函数:

function1()  # No need to handle the errors explicitly

无需担心每次调用时显式处理错误。