3

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

或者两者都不是最理想的?我似乎经常为错误日志编写这类包装函数,并且想知道最 Pythonic 的方法。对此的任何建议将不胜感激。

4

4 回答 4

5

最好不要在异常时返回任何东西,我同意马克的观点 - 没有必要在异常时返回任何东西。

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
于 2012-11-14T12:11:21.957 回答
2

第二个版本在我看来还可以,但第一个版本有点破。例如,如果 try-except 中的代码引发了除了 之外的任何内容ConnectionError,您仍然会返回,{}因为返回 from会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

这允许更精确地定义异常范围。

于 2012-11-14T12:14:32.803 回答
1

第二个对我来说似乎更清楚。

第一个版本有点混乱。起初,我认为您将两次分配给同一个变量是一个错误。只是经过一番思考,我才明白为什么会这样。

于 2012-11-14T12:05:19.787 回答
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
于 2012-11-14T12:48:13.693 回答