Python 中的斷言與異常該怎麼選擇?

Python 中的斷言與異常該怎麼選擇?

異常,在程序運行時出現非正常情況時會被拋出,比如常見的名稱錯誤、鍵錯誤等。

 

斷言,判斷某個表達式的真假,真則程序繼續執行,否則拋出 AssertionError 異常。

理解這兩個概念不難,但是什麼時候使用誰卻讓很多開發者難以選擇。本文呢,我會舉一些例子,說明使用斷言或異常的合適場景,並作小結。當然,只是個人經驗,有不合理的地方也請指出。

什麼時候使用斷言

你可以使用斷言去檢查代碼中的確定量。確定量怎麼理解?在當前情境下,確定量總會滿足特定條件。比如,在某段代碼裏,變量 x 的值始終應該在 0 到 1 之間。

斷言能夠幫助別人或未來的你理解代碼,找出程序中邏輯不對的地方。一方面,斷言會提醒你某個對象應該處於何種狀態,另一方面,如果某個時候斷言爲假,會拋出 AssertionError 異常,很有可能終止程序。

下面是一些斷言有用的地方

例一

例二

比如你在網上填調查問卷時,一個單選題,往往有個自定義選項,當你選擇該項時,需要自己填寫相應的內容。

例三

參數校驗

有的時候斷言會被用到函數參數校驗的地方,我們應該避免這種使用方式。因爲,如果 Python 以 -O 選項執行的話,assert 語句會被跳過。這樣的話,我們的校驗語句都會失效。

斷言爲假觸發的異常的語義相比於一般的異常也不太明確。比如,當需要使用 int 類型的時候用戶傳入 string 類型手動觸發一個 TypeError ,或是當需要正數但接收到負數的時候手動觸發一個 ValueError ,都比 AssertionError好理解一些。

例一

像這種情況,使用異常顯然更好。

例二

假設我們要在 LDAP 服務器上的一個組中刪除或編輯一個用戶

這個情況下,用斷言更合適。因爲 _modify_group() 是在程序內部被調用的,而不會被用戶手動調用。

我們應該拋出哪種類型的異常

編寫代碼的時候,學會使用一些內建的異常,特別是 ValueError 、AttributeError 、TypeError 和 RuntimeError 。常見的庫拋出的異常都是有規律的,很多庫都有一個基本的異常類型。比如,Requests 的自定義異常都是繼承的 RequestError 。

如果有人使用你的庫,這樣的話他們就能比較方便的捕捉相應的異常。如果你拋出各式各樣的異常,又沒有文檔說明,很多時候用戶便會捕捉一個大範圍的異常,比如 [Base]Exception 等。

記住,儘量避免捕獲 [Base]Exception ,這個有不少副作用。它可能會捕捉到(也有可能忽略)鍵盤中斷( KeyboardInterrupt )( CTRL + C)或斷言錯誤( AsstionError )等異常。所以,你也不應該拋出 [Base]Exception 異常。

小結

* 使用斷言去檢測程序中理論上不應該出現的情況。注意 Python 帶 -O 選項執行時,斷言會被忽略。

* 當由用戶輸入或者外部環境(比如網絡延遲、文件不存在等)引起的問題時,我們應拋出異常。

* 儘量避免拋出或捕獲 [Base]Exception 。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章