문제

This is a general, best-practice question. Which of the following try-except examples is better (the function itself is a simple wrapper for 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

or

def get(self, url, params=params):
    try:
        return requests.get(url, params=params)
    except requests.ConnectionError,e:
        log.exception(e)
        return {}

Or perhaps both are suboptimal? I seem to write these kind of wrapper functions fairly often for error logging and would like to know the most Pythonic way of doing this. Any advice on this would be appreciated.

도움이 되었습니까?

해결책

It is better to return nothing on exception, and I'm agree with Mark - there is no need to return anything on exception.

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

다른 팁

The second version looks ok to me, but the first one is slightly broken. For example, if the code inside try-except raises anything but ConnectionError, you'll still return {} since returning from finally suppresses any exceptions. And this latter feature is quite confusing (I had to try it myself before answering).

You can also use else clause with 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

This allows defining the exception scope more precisely.

The second seems clearer to me.

The first version is a little confusing. At first I though it was an error that you were assigning to the same variable twice. It was only after some thought that I understood why this works.

I'd probably look at writing a context manager.

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

Then:

with get(...) as res:
    print res # will be actual response or empty dict
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top