在方法定义或调用方法中使用 try 异常/捕获?



以下哪个代码段代码是常见的?

#1:

def foo():
try:
pass  # Some process
except Exception as e:
print(e)
foo()

#2:

def foo():
pass  # Some process
try:
foo()
except Exception as e:
print(e)

这取决于foo做什么,以及Exception的类型,我会说。

调用方应该处理它还是应该处理方法?

例如,请考虑以下示例:

def try_get_value(registry, key):
try:
return registry[key]
except KeyError:
return None

此函数将尝试使用其键从字典中获取值。如果该值不存在,则应返回None

该方法应该处理KeyError,因为它需要在发生这种情况时返回None,以便符合其预期行为。(捕获此错误是方法的责任)

但是考虑其他异常类型,例如TypeError(例如,如果注册表不是dict)。

为什么我们的方法应该处理这个问题?这就是呼叫者混乱。他应该处理这个问题,他应该担心这一点。

此外,如果我们得到这样的Exception,我们的方法能做什么?我们无法从这个范围处理这个问题。

try_get_value有一个简单的任务:从注册表中获取一个值(如果没有,则为默认值)。它不对调用方违反规则负责。

所以我们没有抓住TypeError,因为这不是我们的责任

因此,调用方的代码可能如下所示:

try:
value = try_get_value(reg, 'some_key')
# Handle value
except TypeError:
# reg is not a dict, do something about it...

PS:如果出现意外退出,我们的foo方法有时可能需要进行一些清理(例如,它分配了一些资源,如果不关闭就会泄漏)。

在这种情况下,foo应捕获异常,以便它可以适当地修复其状态,但随后应将它们再次raise回调用方。

我认为第一部分更干净,更优雅。也更合乎逻辑,因为作为函数的实现者,您希望处理它可能引发的所有异常,而不是将其留给客户端或调用方。即使你是唯一使用该方法的人,你仍然希望处理函数内部的异常,因为将来你可能不记得它抛出的异常。

最新更新