Python 异常处理块的正确范围

Python 异常处理块的正确范围,python,exception,error-handling,code-readability,Python,Exception,Error Handling,Code Readability,假设我们有以下代码: print("...") might_throw_type_error() print("...") might_throw_index_error() 如果我们想处理这些功能可能出现的异常,首选的方法是: 完全拆分“业务”代码和错误处理 try: print("...") might_throw_type_error() print("...") might_throw_index_error() except IndexError:

假设我们有以下代码:

print("...")
might_throw_type_error()
print("...")
might_throw_index_error()
如果我们想处理这些功能可能出现的异常,首选的方法是:


完全拆分“业务”代码和错误处理

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

请注意,如果我们捕获异常,我们不想继续< /p> < p>它完全取决于您想要实现什么——如果使用第一个<代码> MyTyPosixIdxxIrror 下面的<代码>打印< /代码>和第二个代码> MyLyPosixIdxxOrth.<代码>,请考虑使用1的方法。将永远不会执行

另一方面,最后一个可以保证至少secon
print
会一直启动

这些方法都很好,但这取决于您希望对应用程序流执行什么操作。

创建一个装饰器,并将该装饰器添加到每个函数定义中。查看详细信息。例如,您的装饰者应该是:

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

不必担心每次调用时都会显式处理错误。

这完全是基于意见的。。。也许更适合这样的问题。很高兴移动它,以防有“蟒蛇式”的答案:$这真的不是蟒蛇式的问题,而是品味的问题。CodeReview可能会说同样的话。对不起,忘记添加了。异常处理只是记录和重新发布(因此逻辑是相同的)。让我更新一下这个问题答案还是一样的-唯一重要的是如果你想在第一次失败的情况下尝试触发第二种方法-如果不是,没有理由不把它们放在一个
中,那么你不同意“异常处理应该只包装我们希望提出的语句”这句话。这样做的理由是,如果您看到100个
try except
块一个接一个地比包含多个
except
块的块可读性更强,那么读者可以更清楚地了解是什么函数引发了特定类型的异常这是您的选择。如果我有一个进程可以在多个地方被破坏,但在任何情况下肯定应该停止,那么我总是使用一个
try except
块。“显式优于隐式”,并且在装饰器中包装异常就像我看到的一样是可怕的隐式。这取决于需求对需求。我对此的看法略有不同。据我所知,这是更好的。假设要将条目写入日志文件。后来要求改变了,现在你还需要发送电子邮件。您会在处理异常的每个地方修改代码吗?它提供了一种更干净的方式。您的函数代码与讨厌的try/except隔离,您的主要函数是干净的,并且decorator坐在角落里管理所有讨厌的任务