Python try except块重新引发异常

Python try except块重新引发异常,python,pep,Python,Pep,不捕获内部函数的异常,而是在调用外部函数时捕获异常,这是一种不好的做法?让我们看两个例子: 备选方案a) 赞成:清洁剂(在我看来) 缺点:如果不查看foo 备选方案b) 赞成:明确的 缺点:您正在编写一个try-except块来重新引发异常。在我看来,这也很难看 其他选择 我理解,如果您想处理异常或将多个异常组合在一起,选项b是唯一的选择。但是,如果您只想按原样重新提出一些特定的异常,该怎么办 我在PEP中找不到任何能说明这一点的东西。如果你遵循Bob叔叔的干净代码手册,你应该始终将逻辑和错误处

不捕获内部函数的异常,而是在调用外部函数时捕获异常,这是一种不好的做法?让我们看两个例子:

备选方案a)

赞成:清洁剂(在我看来)
缺点:如果不查看
foo

备选方案b)

赞成:明确的
缺点:您正在编写一个try-except块来重新引发异常。在我看来,这也很难看

其他选择

我理解,如果您想处理异常或将多个异常组合在一起,选项b是唯一的选择。但是,如果您只想按原样重新提出一些特定的异常,该怎么办


我在PEP中找不到任何能说明这一点的东西。

如果你遵循Bob叔叔的干净代码手册,你应该始终将逻辑和错误处理分开。这将使选项a.)成为首选解决方案

我个人喜欢这样命名函数:

def_foo(a,b):
返回a/b
def try_foo(a,b):
尝试:
返回(a,b)
除零误差外:
打印('错误')
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
试试(5,0)

如果您遵循Bob叔叔的干净代码手册,您应该始终将逻辑和错误处理分开。这将使选项a.)成为首选解决方案

我个人喜欢这样命名函数:

def_foo(a,b):
返回a/b
def try_foo(a,b):
尝试:
返回(a,b)
除零误差外:
打印('错误')
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
试试(5,0)
处理错误 这是个坏习惯吗?依我看:不,不是。一般来说,这是一种良好的做法:

def foo(a,b):
返回a/b
def巴(a):
返回foo(a,0)
尝试:
酒吧(6)
除零误差外:
打印(“错误!”)
原因很简单:处理错误的代码集中在主程序中的一个点上

在某些编程语言中,可能引发的异常必须在函数/方法级别声明。Python则不同:它是一种脚本语言,缺少这样的特性。当然,因此,有时您可能会意外地遇到异常,因为您可能不知道正在调用的其他代码可能会引发这样的异常。但这没什么大不了的:要解决这种情况,您需要在主程序中使用
try…除了…

您可以通过以下方式弥补对可能异常的了解不足:

  • 记录可能提出的例外情况;如果编程语言本身没有帮助,您需要通过提供更广泛的文档来弥补这一缺陷
  • 进行广泛的测试
一般来说,遵循您的选项b)毫无意义。事情可能更加明确,但代码本身并不是这个明确信息的正确位置。相反,这些信息应该是函数/方法文档的一部分

因此,不是

def条(a):
尝试:
ret=foo(a,0)
除零误差外:
提升
回程网
。。。写:

def条(a):
"""
可能会引起错误
"""
返回foo(a,0)
或者像我写的那样:

#
#@throws zero错误不适用于零。
#
def巴(a):
返回foo(a,0)
(但您在文档中究竟依赖哪种语法是完全不同的问题,超出了本问题的范围。)

在某些情况下,捕获函数/方法中的异常是一种很好的做法。例如,如果您希望某个方法以任何方式成功,即使某些内部操作可能失败,也会出现这种情况。(例如,如果您试图读取一个文件,但如果该文件不存在,您希望使用默认数据。)但仅仅为了再次引发异常而捕获异常通常没有任何意义:目前我甚至无法想出这样做可能有用的情况(尽管可能有一些特殊情况)。如果您希望提供可能引发此类异常的信息,请不要依赖用户查看实现,而是查看函数/方法的文档

输出错误 无论如何,我不会按照您的方法只打印一条简单的错误消息:

试试看:
酒吧(6)
除零误差外:
打印(“错误!”)
提出合理的、人类可读的、简单的错误消息是相当费力的。我曾经这样做过,但是这种方法需要的代码量是巨大的。根据我的经验,最好是失败并打印出堆栈跟踪。使用此堆栈跟踪,通常任何人都可以很容易地找到错误的原因

不幸的是,Python在错误输出中没有提供非常可读的堆栈跟踪。为了弥补这一点,我实现了自己的错误输出处理(可重用为模块),甚至使用了颜色,但这是另一回事,可能也有点超出了这个问题的范围。

处理错误 这是个坏习惯吗?依我看:不,不是。一般来说,这是一种良好的做法:

def foo(a,b):
返回a/b
def巴(a):
返回foo(a,0)
尝试:
酒吧(6)
除零误差外:
打印(“错误!”)
原因很简单:处理错误的代码集中在主程序中的一个点上

在某些编程语言中,可能引发的异常必须在函数/方法级别声明。Python则不同:它是一种脚本语言,缺少这样的特性。当然,因此,有时您可能会意外地遇到异常,因为您可能不知道正在调用的其他代码可能会引发这样的异常。但这没什么大不了的:要解决这种情况,你可以在你的主程序中使用
尝试…除了…
def foo(a, b):
    return a / b

def bar(a):
    return foo(a, 0)

try:
    bar(6)
except ZeroDivisionError:
    print("Error!")
def foo(a, b):
    return a / b

def bar(a):
    try:
        ret = foo(a, 0)
    except ZeroDivisionError:
        raise

    return ret

try:
    bar(6)
except ZeroDivisionError:
    print("Error!")