假设我有一个代码片段如下
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中处理异常的最佳方法是什么。
答案 0 :(得分:5)
在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))
这体现了几个最佳实践,例如:详细的错误消息,总是重新引发您不知道如何专门处理的异常(在记录错误消息以及更多详细信息和异常之后),从不提出某些内容泛型为Exception
,& c - 而且,至关重要的是,仅在代码的最窄部分捕获异常,这就是else:
中try/except
子句的含义强>! - )
如果您希望 - 并且知道如何处理 - 特定的异常,那就更好了 - 您将其他except ThisSpecificProblem as e:
子句置于通用except Exception
子句之前,该子句记录并重新生成加注。但是(来自Python的Zen - import this
在Python解释器提示!) - “错误永远不应该默默传递.//除非明确地沉默。”......你应该只是“明确地保持”错误你完全期待,和完全知道如何处理!
答案 1 :(得分:4)
我刚刚处理了一个通用例外,并且不知道究竟是什么 这条线会引发异常,找到最好的方法是什么 它在python中。
与往常一样,答案是看the documentation:
如果出现网络问题(例如DNS失败,请拒绝 连接等),请求将引发ConnectionError异常。
在极少数情况下,HTTP响应无效,请求将引发 HTTPError异常。
如果请求超时,则会引发超时异常。
如果请求超过配置的最大重定向数,则a 引发了TooManyRedirects异常。
请求显式引发继承自的所有异常 requests.exceptions.RequestException。
记录引发异常的代码(特别是如果存在自定义异常)。如果文档不明确,您还可以查看source。
您的代码很好,除非您应该避免泛型除了子句,因为这些可以隐藏代码的其他问题。除了那些你可以预测的例外情况,你应该让其他人出现并且#34;起来"直到被抓住/记录。
答案 2 :(得分:2)
好吧,回答你的第一个问题,这一行会引发什么样的例外,你就是一步之遥。
您已拨打except Exception as e
,但未在任何地方使用e
。 e
包含有关您的异常的信息,因此只需添加一点印刷语句
print e
它有效:
>>> try:
... x = int(raw_input('Input: '))
... except Exception as e:
... print e
...
Input: 5t
invalid literal for int() with base 10: '5t'
>>>
我并不完全看到你在2 nd 中提出的问题,你说它是丑陋的/非pythonic,但是你说它没问题。是的,它 很好,在我看来它也是非常pythonic。
答案 3 :(得分:0)
您应尽量避免使用except Exception as e:
。
为清楚起见,您可以创建一个自定义异常类来处理错误代码= 200场景。
class PostingError(Exception):
pass
然后只提升PostingError
。请尝试仅捕获此错误。通过捕获各种错误,您可能会捕获错误的信息。例如,即使是内存错误也可能被捕获并显示为"错误发布到URL"。
所以这就是最终的样子
try:
r = requests.post(url, data=values, files=files)
if r.status_code != 200:
raise PostingError("Could not post to "+ url)
except PostingError as e:
logger.error(e)