2015-04-02 68 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在他們身上。

相關問題