以下哪个代码段是常见的?
#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
有一个简单的任务:从注册表中获取一个值(如果没有,则为默认值)。它不对打电话者违反规则负责。
因此,我们不会抓住qazxsw poi,因为这不是我们的责任。
因此,调用者的代码可能如下所示:
TypeError
P.S。:有时我们的try:
value = try_get_value(reg, 'some_key')
# Handle value
except TypeError:
# reg is not a dict, do something about it...
方法需要进行一些清理,如果出现意外退出(例如,它已经分配了一些资源,如果没有关闭则会泄漏)。
在这种情况下,foo
应该捕获异常,只是因为它可以适当地修复它的状态,但是然后应该再次将它们返回给调用者。
我认为第一部分更干净,更优雅。也更合乎逻辑,因为作为函数的实现者,您希望处理它可能抛出的所有异常,而不是将其留给客户端或调用者。即使你是唯一使用该方法的人,你仍然希望处理函数内部的异常,因为将来你可能不记得它抛出的异常。