2013-11-25 91 views
0

我有以下Python函數:爲什麼這個「if」語句中的代碼仍然運行?

api_function: 
    try: 
     # api query 
    except: 
     # api error #1 
     return "api error 1" 
    except: 
     # api error #2 
     return "api error 2" 
    else: 
     return api_data_dict 

我要運行這個功能,如果沒有錯誤,分析數據從API返回:

for call in api_call_list: 
    raw_api_data = api_function(access_token) 
     if raw_api_data != 'api error 1' or 'api error 2': 
      page_name = raw_api_data['name'] 
      # process api data 

當我運行代碼,只要API正在運行,它就可以正常運行。然而,當API命中錯誤,if聲明似乎並沒有趕上串 - 相反,我得到了回溯:

Traceback (most recent call last): 
    File "api_retriever.py", line 4, in <module> 
    page_name = raw_api_data['name'] 
TypeError: string indices must be integers, not str 

爲什麼我if聲明捕捉錯誤字符串返回由我api_function並防止第4行甚至運行?

+0

捕獲異常並返回錯誤代碼 - 這調用者必須檢查 - 而不是讓呼叫者捕獲異常是一個比較奇怪的圖案。或者我應該說一個反模式? –

+0

不知道我會如何構建這個。如果api調用成功返回,我只想解析api數據。由於我多次使用該函數,並且每次我想稍微不同地處理數據,因此無法將處理api數據的邏輯真正放入api調用函數中。 –

+0

要麼讓異常傳播並在上層捕獲它們(如果存在太多不同的異常類型,最好將它們包裝起來以簡化它們),或者捕獲它們並在'api_function'級別記錄它們,然後返回'None'。有例外的要點是爲了避免錯誤代碼... –

回答

4

這行代碼的:

if raw_api_data != 'api error 1' or 'api error 2': 

實際上被解釋爲

if (raw_api_data != 'api error 1') or ('api error 2'): 

和Python中的非空字符串將始終爲true。

您應使用:

if (raw_api_data != 'api error 1') and (raw_api_data != 'api error 2'): 

if not raw_api_data in ('api error 1', 'api error 2'): 
+0

「您應該使用:」中的代碼將始終輸入if。 ;) – Mailerdaimon

+0

@Mailerdaimon非常感謝您指出。我已修復>< – starrify

2

Or被稱爲邏輯或運算符。如果兩個操作數中的任何一個都不爲零,則條件成立。 (source

使用這個代替:

if (raw_api_data != 'api error 1') and (raw_api_data != 'api error 2'):