不捕获内部函数的异常,而是在调用外部函数时捕获异常,这是一种不好的做法?让我们看两个例子:
备选方案a)
def foo(a, b):
return a / b
def bar(a):
return foo(a, 0)
try:
bar(6)
except ZeroDivisionError:
print("Error!")
赞成:清洁剂(在我看来)
反对:如果不查看foo
,就无法判断bar
引发了哪些异常
备选方案b)
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!")
赞成:明确的
缺点:您正在编写一个try-except块来重新引发异常。在我看来,这也很难看
其他选择
我理解,如果您想处理异常或将多个异常组合在一起,选项b是唯一的选择。但是,如果您只想按原样重新提出一些特定的异常,该怎么办
我在政治公众人物中找不到任何能说明这一点的东西
处理错误
这是个坏习惯吗?依我看:不,不是。一般来说,这是一种良好的做法:
原因很简单:处理错误的代码集中在主程序中的一个点上
在某些编程语言中,可能引发的异常必须在函数/方法级别声明。Python则不同:它是一种脚本语言,缺少这样的特性。当然,因此,有时您可能会意外地遇到异常,因为您可能不知道正在调用的其他代码可能会引发这样的异常。但这没什么大不了的:要解决这种情况,您的主程序中有
try...except...
您可以通过以下方式弥补对可能异常的了解不足:
一般来说,遵循您的选项b)毫无意义。事情可能更加明确,但代码本身并不是这个明确信息的正确位置。相反,这些信息应该是函数/方法文档的一部分
因此,不是
。。。写:
或者像我写的那样:
(但您在文档中究竟依赖哪种语法是完全不同的问题,超出了本问题的范围。)
在某些情况下,捕获函数/方法中的异常是一种很好的做法。例如,如果您希望一个方法以任何方式成功,即使某些内部操作可能失败,也会出现这种情况。(例如,如果您试图读取一个文件,但如果该文件不存在,您希望使用默认数据。)但仅仅为了再次引发异常而捕获异常通常没有任何意义:目前我甚至无法想出这样做可能有用的情况(尽管可能有一些特殊情况)。如果您希望提供可能引发此类异常的信息,请不要依赖用户查看实现,而是查看函数/方法的文档
输出错误
无论如何,我不会按照您的方法只打印一条简单的错误消息:
提出合理的、人类可读的、简单的错误消息是相当费力的。我曾经这样做过,但是这种方法需要的代码量是巨大的。根据我的经验,最好是失败并打印出堆栈跟踪。使用此堆栈跟踪,通常任何人都可以很容易地找到错误的原因
不幸的是,Python在错误输出中没有提供非常可读的堆栈跟踪。为了弥补这一点,我实现了自己的错误输出处理(可重用为模块),甚至使用了颜色,但这是另一回事,可能也有点超出了这个问题的范围
如果您遵循Bob叔叔的干净代码手册,那么您应该始终将逻辑和错误处理分开。这将使选项a.)成为首选解决方案
我个人喜欢这样命名函数:
相关问题 更多 >
编程相关推荐