翻譯自StackOverflow中一個關(guān)于Python異常處理的問答。
問題:為什么“except:pass”是一個不好的編程習(xí)慣?
我時常在StackOverflow上看到有人評論關(guān)于except: pass的使用,他們都提到這是一個不好的Python編程習(xí)慣,應(yīng)該避免。可我想知道為什么?有時候我并不在意出現(xiàn)的錯誤,而是只想讓我的程序繼續(xù)進行下去。就像這樣:
try: somethingexcept: pass
為什么這么使用except:pass不好?這背后的原因是什么,是不是因為這樣我會放掉一些本該被處理的錯誤?還是這樣我會捕獲到所有類型的錯誤?
最佳回答:
正如你所猜測的那樣,這么做的確有兩個不好的地方。首先,因為沒有指定任何異常類型,所以會捕獲到任何類型的錯誤。其次,捕獲到錯誤之后只會簡單地讓它通過而不是采取必要的處理措施。
我接下來的解釋或許會有點長,所以將重點總結(jié)如下:
1. 不要將任意類型的錯誤作為捕獲對象。必須明確你想要捕獲的錯誤類型,并且寫明只捕獲它們。
2. 不要試圖簡單地敷衍錯誤處理動作。除非這么做是有目的的,但這通常都不太好。
那么接下來讓我們更深入一些:
不要將任意異常作為捕獲目標
當(dāng)在代碼中的某個地方使用異常捕獲語句塊時,你通常知道這個地方可能會拋出異常,并且你也知道這個地方可能會發(fā)生什么樣的問題進而拋出何種異常,一旦異常被拋出,你將捕獲到這個異常并使程序回到正軌上來。這就意味著你一定對這種異常有所準備,并能夠在它發(fā)生的時候及時采取措施進行處理。
舉個例子,你需要用戶輸入一個數(shù)字,并且使用int()函數(shù)將用戶輸入的字符串轉(zhuǎn)換為整數(shù)類型,這時候你一定會想到如果輸入的字符串并不是數(shù)字,那么就會發(fā)生值錯誤(ValueError)。如果真的發(fā)生了錯誤,那么你可以通過簡單的讓用戶重新輸入來讓程序回到正軌,所以捕獲值錯誤以及促使用戶重新輸入就是一個比較合理的處理策略。再舉一個例子,如果你想從一個文件中讀取配置信息,但正巧這個文件不存在。那么因為這是一個配置文件,如果它不存在你會返回一些默認的配置選項,所以這個文件就不是這么必要了。在這個例子中,捕獲文件未找到錯誤(FileNotFoundError)以及返回默認配置項則是一個比較合適的處理策略。通過以上兩個例子可以看到,我們都是在等待捕獲特定的錯誤,并且針對每種錯誤都有特定的處理策略。
然而,如果我們在這里捕獲所有的異常,那么為特定異常準備的那些處理策略就會因為遇到非正常類型的異常而失效,這將會使得正常的程序流程中斷并且無法恢復(fù)。
讓我們還是舉配置文件的那個例子。正常的處理策略是如果發(fā)現(xiàn)文件并不存在,我們將使用默認的配置項,并可能在稍后決定是否將當(dāng)前的配置項自動保存為配置文件(這樣的話下一次文件就肯定存在了)。現(xiàn)在讓我們假定我們捕獲到了一個IsADirectoryError或是PermissionError錯誤,在這種情況下,我們可能不想讓程序繼續(xù)執(zhí)行,我們?nèi)匀荒軌蚴褂媚J的配置參數(shù),但是隨后我們就不能保存文件了。也有可能用戶希望使用自定義的配置項,所以這樣的話就不能使用默認配置項了。所以我們這時候可能需要立即告知用戶并停止當(dāng)前程序。也有可能我們并不想在這么一小塊代碼中做這么多的事情,而是讓應(yīng)用層面的部分去關(guān)心它,所以我們也可能讓這個錯誤浮到頂層,讓頂層的業(yè)務(wù)邏輯去處理。
新聞熱點
疑難解答
圖片精選