过分热心的条款
异常是强大的,但是一个过分热心的 except 子句可以将它全部带到一行。
try:
res = get_result()
res = res[0]
log('got result: %r' % res)
except:
if not res:
res = ''
print('got exception')
此示例演示了反模式的 3 个症状:
- 没有例外类型的
except
(第 5 行)将捕获甚至健康的例外,包括KeyboardInterrupt
。这将阻止程序在某些情况下退出。 - except 块不会重新加载错误,这意味着我们无法判断异常是来自
get_result
还是因为res
是一个空列表。 - 最糟糕的是,如果我们担心结果是空的,我们会导致更糟糕的事情。如果
get_result
失败,res
将保持完全未设置,并且在 except 块中对res
的引用将提升NameError
,完全屏蔽原始错误。
始终考虑你尝试处理的异常类型。给异常页面一个读取, 并了解存在哪些基本异常。
以下是上述示例的固定版本:
import traceback
try:
res = get_result()
except Exception:
log_exception(traceback.format_exc())
raise
try:
res = res[0]
except IndexError:
res = ''
log('got result: %r' % res)
我们会捕获更具体的例外情况,并在必要时重新加注。还有几行,但无限正确。