这是一个一般性的最佳实践问题。以下哪个try-except示例更好(函数本身是requests.get()的简单包装器):
def get(self, url, params=params):
try:
response = {}
response = requests.get(url, params=params)
except requests.ConnectionError,e:
log.exception(e)
finally:
return response
或
def get(self, url, params=params):
try:
return requests.get(url, params=params)
except requests.ConnectionError,e:
log.exception(e)
return {}
或许两者都不是最理想的?我似乎经常为错误记录编写这些包装函数,并且想知道最恐怖的方式。对此有任何建议将不胜感激。
答案 0 :(得分:5)
最好不要在异常中返回任何内容,我同意Mark - 没有必要在异常时返回任何内容。
def get(self, url, params=params):
try:
return requests.get(url, params=params)
except requests.ConnectionError,e:
log.exception(e)
res = get(...)
if res is not None:
#Proccess with data
#or
if res is None:
#aborting
答案 1 :(得分:2)
第二个版本对我来说没什么问题,但是第一个版本有点坏了。例如,如果try-except中的代码引发了除ConnectionError
以外的任何内容,您仍将返回{}
,因为从finally
返回会抑制任何异常。后一个功能非常令人困惑(我必须在回答之前自己尝试一下)。
您还可以将else
子句与try
:
def get(self, url, params=params):
try:
# Do dangerous some stuff here
except requests.ConnectionError,e:
# handle the exception
else: # If nothing happened
# Do some safe stuff here
return some_result
finally:
# Do some mandatory stuff
这允许更精确地定义异常范围。
答案 2 :(得分:1)
第二个对我来说更清楚。
第一个版本有点令人困惑。起初我虽然错误的是你分配给同一个变量两次。只有经过一番思考,我才明白为什么会这样。
答案 3 :(得分:0)
我可能会考虑编写一个上下文管理器。
from contextlib import contextmanager
@contextmanager
def get(url, params=params):
try:
yield requests.get(url, params=params)
except requests.ConnectionError as e:
log.exception(e)
yield {}
except:
raise # anything else stays an exception
然后:
with get(...) as res:
print res # will be actual response or empty dict