用于异常处理的首选Python样式

时间:2012-11-14 12:01:55

标签: python syntax try-except

这是一个一般性的最佳实践问题。以下哪个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 {}

或许两者都不是最理想的?我似乎经常为错误记录编写这些包装函数,并且想知道最恐怖的方式。对此有任何建议将不胜感激。

4 个答案:

答案 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