2015-04-02 80 views
3

在我的程序中,我有一个处理requests调用的函数,并返回处理的调用或引发异常。这个函数被许多其他函数使用,但是我遇到的问题是如何处理可能会引发的异常。目前,它是建立像这样(简化):Python:有没有办法强制父函数返回?

def getFromAPI(url): 
    # create variable headers 
    r = requests.get(url, headers=headers) 
    if r.status_code == 404: 
     raise Exception("Error raised") 
    else: 
     #process data 
     return data 

def functionone(): 
    ... 
    try: 
     data = getFromAPI(url) 
    except Exception as e: 
     return handleException(e) 
     #handles problems, returns exception-formatted data 

    ... 
    # formatting data specific to functionone 
    return formatted_data 

def functiontwo(): 
    ... 
    try: 
     data = getFromAPI(url) 
    except Exception as e: 
     return handleException(e) 
     #handles problems, returns exception-formatted data 

    ... 
    # formatting data specific to functiontwo 
    return formatted_data 

def functionthree(): 
    ... 
    #similar to functionone and functiontwo 

虽然我不认为这是错误的本身,因为getFromAPI在如此多的功能使用,不必不断地重复尝试,除了陈述感觉错,好像它应该在功能getFromAPI内处理。但是,由于其他functiononefunction_n都会根据是否出现错误返回不同的内容,因此我无法在getFromAPI之内找到处理该问题的方法,除非有办法让getFromAPI强制它的父函数返回,而没有显式调用父函数中的返回值。

失败了,有没有更好的实现我想要做的,或者我注定要不断重复try语句除外?

+0

让它大声地失败并进一步捕捉它......不处理每个函数中的问题 – 2015-04-02 17:47:31

+0

不幸的是,我没有进一步控制功能。 – echolocation 2015-04-02 17:50:51

+0

“进一步”确实意味着'functionone'..''functionthree'的调用者?或者'getFromAPI'的直接调用者? – kdopen 2015-04-02 17:55:05

回答

8

这样写

def catchAPIException(func): 
    def wrapper(*args, **kwargs) 
     try: 
      return func(*args, **kwargs) 
     except getFromAPIException as e: 
      return handleException(e) 
    return wrapper 

一个装饰那么你functionone等只是看起来像

@catchAPIException 
def functionone(): 
    ... 
    data = getFromAPI(url) 
    ... 
    # formatting data specific to functionone 
    return formatted_data 

但是你要提出一个非常具体的定制例外,这样你的装饰将赶上相关的一个。或者,也许你应该创建一些不同的例外,这些例外可以被不同地处理。

如果不同的函数想要以自定义的方式格式化异常,修饰器可以传递另一个实际用于格式化的函数。即让handleException参数来catchAPIException

def catchAPIException(exceptionHandler = handleException): 
    def real_decorator(func): 
     def wrapper(*args, **kwargs) 
      try: 
       return func(*args, **kwargs) 
      except getFromAPIException as e: 
       return exceptionHandler(e) 
     return wrapper 
    return real_decorator 

然后函数,它们喜欢默认的异常处理程序的声明如下:

@catchAPIException 
def function1(): 
    ... 

其他更具体的需求,可以这样做:

def customExceptionHandler(e): 
    ... 

@catchAPIException(customExceptionHandler) 
def function2(): 
    ... 

如果你不熟悉装饰器,这里是reasonable tutorial,还有Python文档,虽然他们没有明确的s在他们身上。

相关问题