2014-12-21 94 views
1

假設我有一個代碼段如下除Python之外,編寫try的最佳方式是什麼?

r = requests.post(url, data=values, files=files) 

由於這是進行網絡請求,一束異常可以從該線被拋出。對於參數的完整性,我也可以有文件讀取,發送電子郵件等。要遇到這樣的錯誤,我做

try: 
    r = requests.post(url, data=values, files=files) 
    if r.status_code != 200: 
    raise Exception("Could not post to "+ url) 
except Exception as e: 
    logger.error("Error posting to " + url) 

有兩個問題,我用這種方法看到的。

  1. 我剛剛處理了一個泛型異常,不知道這行會產生什麼樣的確切異常,在python中找到它的最好方法是什麼。
  2. 這使得代碼看起來很醜,這是非pythonic,但罰款,只要它的健壯和處理所有情況。

我想知道什麼是在python中處理異常的最佳方法。

回答

2

那麼,回答你的第一個問題,這條線會提出什麼樣的確切例外,你只有一步之遙。

您已致電except Exception as e,但您不要在任何地方使用ee包含有關異常的信息,所以只加一點print語句

print e

而且它的工作原理:

>>> try: 
...  x = int(raw_input('Input: ')) 
... except Exception as e: 
...  print e 
... 
Input: 5t 
invalid literal for int() with base 10: '5t' 
>>> 

我完全不明白你問什麼在2 nd,你說這是醜陋的/非pythonic,但你說它是好的。是的,它很好,在我看來,它也相當pythonic。

+0

我不知道爲什麼這個答案獲得了反對票,因爲它似乎是這個問題的一個非常簡單,容易回答。 – kartikg3

+0

@ kartikg3 :)謝謝 –

+0

As @ A.J。說,除了_is_是處理異常的最好方法之外。如果你知道會發生什麼樣的異常以及你處理它們的步驟,那麼就趕上那些異常並處理它們。使用'Exceptions'作爲所有其他/默認/未知情況的默認例外。 – kartikg3

3

我剛纔處理一般異常,不知道什麼確切的 例外是由該行提出,什麼是找到 它在Python的最好方式。

像往常一樣,答案是看the documentation

在網絡出現問題時(如DNS故障,拒絕 連接等),要求將引發一個ConnectionError例外。

在罕見的HTTP響應無效的情況下,請求將引發一個HTTP錯誤異常 。

如果請求超時,則會引發超時異常。

如果請求超過配置的最大重定向次數,則會引發 TooManyRedirects異常。

請求顯式引發的所有異常都會從 requests.exceptions.RequestException繼承。

記錄引發異常(尤其是如果有自定義異常)的代碼。如果文檔不明確,您也可以查看source

你的代碼是好的,除非你應該避免泛型除了子句,因爲這些可以隱藏你的代碼的其他問題。你應該除了你可以預測的那些例外,然後讓其他人「起來」直到被捕獲/登錄。

4

編寫try-except - 在Python或其他地方的最好方法是儘可能縮小。捕捉更多的異常比你想要處理的是一個常見的問題!

特別是,至少,我會重新寫你的示例代碼,就像這樣:

try: 
    r = requests.post(url, data=values, files=files) 
except Exception as e: 
    logger.error("Error posting to %r: %s" % (url, e)) 
    raise 
else: 
    if r.status_code != 200: 
    logger.error("Could not to %r: HTTP code %s" % (url, r.status_code)) 
    raise RuntimeError("HTTP code %s trying to post to %r" % (r.status_code, url)) 

這體現了一些最佳實踐,如:詳細的錯誤信息,隨時重新拋出異常你不知道如何特別處理(在記錄更多細節以及異常的錯誤消息之後),千萬不要提出類似於通用的東西,例如Exception,&c - 並且最重要的是隻在代碼的最窄部分捕獲異常可能可以,這就是try/except中的else:子句是對於! - )

如果且當您確實期望 - 並且知道如何處理 - 特定的異常,則好得多 - 您將其他except ThisSpecificProblem as e:子句放在記錄和重新提升的通用except Exception子句之前。但是(來自Python的Zen - import this在Python解釋器提示符下) - 「錯誤不應該默默地傳遞。」//除非明確地聲明爲「...並且您應該只」明確地默認「您完全期望的錯誤,完全知道如何處理!

0

您應儘量避免使用except Exception as e:

爲了清楚起見,您可以創建一個自定義的異常類來照顧您的錯誤代碼= 200場景。

class PostingError(Exception): 
    pass 

然後只提PostingError。嘗試僅捕獲此錯誤。通過捕捉各種錯誤,你可能會捕獲錯誤的信息。例如,即使內存錯誤可能被捕獲並顯示爲「發佈到URL的錯誤」。

所以這是它會是什麼樣子終於

try: 
    r = requests.post(url, data=values, files=files) 
    if r.status_code != 200: 
    raise PostingError("Could not post to "+ url) 
except PostingError as e: 
    logger.error(e) 
相關問題