假设我有如下代码片段
r = requests.post(url, data=values, files=files)
因为这是一个网络请求,所以这一行会抛出一堆异常。为了论证的完整性,我还可以读取文件、发送电子邮件等。遇到此类错误我会遇到
try:
r = requests.post(url, data=values, files=files)
if r.status_code != 200:
raise Exception("Could not post to "+ url)
except Exception as e:
logger.error("Error posting to " + url)
我发现这种方法存在两个问题。
- 我刚刚处理了一个通用异常,不知道这一行会引发什么异常,在 python 中找到它的最佳方法是什么。
- 这使代码看起来很丑陋,虽然不是 pythonic 但很好,只要它健壮并能处理所有情况。
我想知道在 python 中处理异常的最佳方法是什么。
请您参考如下方法:
用 Python 或其他任何地方编写 try-except 的最佳方法是尽可能窄。捕获的异常多于您打算处理的异常是一个常见问题!
特别是,至少,我会像这样重写您的示例代码:
try:
r = requests.post(url, data=values, files=files)
except Exception as e:
logger.error("Error posting to %r: %s" % (url, e))
raise
else:
if r.status_code != 200:
logger.error("Could not to %r: HTTP code %s" % (url, r.status_code))
raise RuntimeError("HTTP code %s trying to post to %r" % (r.status_code, url))
这体现了几个最佳实践,例如:详细的错误消息,总是重新引发您不知道如何具体处理的异常(在记录包含更多详细信息和异常的错误消息之后),永远不要引发像generic as Exception, &c —— 而且,至关重要的是,只在代码的最窄部分捕获异常,这就是 try/中的 是 for!-)else: 子句except
如果当你确实期望——并且知道如何处理——特定异常时,那就更好了——你将其他 except ThisSpecificProblem as e: 子句放在通用 except 之前Exception 记录并重新引发的子句。但是(来自 Python 之禅——import this at a Python interpreter prompt!)——“错误不应该悄无声息地传递。//除非明确地沉默。”...你应该只“明确地silence"错误是您完全预料到的,并且完全知道如何处理!
