一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Python - 對于Python異常處理慎用“except:pass”建議

對于Python異常處理慎用“except:pass”建議

2020-05-28 10:14StackOverflow Python

這篇文章主要介紹了對于Python異常處理方法的建議,摘選自StackOverflow上的熱門問題的回答,闡述了except:pass的使用時需要注意的地方,需要的朋友可以參考下

翻譯自StackOverflow中一個關于Python異常處理的問答。

問題:為什么“except:pass”是一個不好的編程習慣?

我時常在StackOverflow上看到有人評論關于except: pass的使用,他們都提到這是一個不好的Python編程習慣,應該避免。可我想知道為什么?有時候我并不在意出現的錯誤,而是只想讓我的程序繼續進行下去。就像這樣:
 

?
1
2
3
4
try:
  something
except:
  pass

為什么這么使用except:pass不好?這背后的原因是什么,是不是因為這樣我會放掉一些本該被處理的錯誤?還是這樣我會捕獲到所有類型的錯誤?

最佳回答:

正如你所猜測的那樣,這么做的確有兩個不好的地方。首先,因為沒有指定任何異常類型,所以會捕獲到任何類型的錯誤。其次,捕獲到錯誤之后只會簡單地讓它通過而不是采取必要的處理措施。

我接下來的解釋或許會有點長,所以將重點總結如下:
1. 不要將任意類型的錯誤作為捕獲對象。必須明確你想要捕獲的錯誤類型,并且寫明只捕獲它們。
2. 不要試圖簡單地敷衍錯誤處理動作。除非這么做是有目的的,但這通常都不太好。

那么接下來讓我們更深入一些:

不要將任意異常作為捕獲目標

當在代碼中的某個地方使用異常捕獲語句塊時,你通常知道這個地方可能會拋出異常,并且你也知道這個地方可能會發生什么樣的問題進而拋出何種異常,一旦異常被拋出,你將捕獲到這個異常并使程序回到正軌上來。這就意味著你一定對這種異常有所準備,并能夠在它發生的時候及時采取措施進行處理。

舉個例子,你需要用戶輸入一個數字,并且使用int()函數將用戶輸入的字符串轉換為整數類型,這時候你一定會想到如果輸入的字符串并不是數字,那么就會發生值錯誤(ValueError)。如果真的發生了錯誤,那么你可以通過簡單的讓用戶重新輸入來讓程序回到正軌,所以捕獲值錯誤以及促使用戶重新輸入就是一個比較合理的處理策略。再舉一個例子,如果你想從一個文件中讀取配置信息,但正巧這個文件不存在。那么因為這是一個配置文件,如果它不存在你會返回一些默認的配置選項,所以這個文件就不是這么必要了。在這個例子中,捕獲文件未找到錯誤(FileNotFoundError)以及返回默認配置項則是一個比較合適的處理策略。通過以上兩個例子可以看到,我們都是在等待捕獲特定的錯誤,并且針對每種錯誤都有特定的處理策略。

然而,如果我們在這里捕獲所有的異常,那么為特定異常準備的那些處理策略就會因為遇到非正常類型的異常而失效,這將會使得正常的程序流程中斷并且無法恢復。

讓我們還是舉配置文件的那個例子。正常的處理策略是如果發現文件并不存在,我們將使用默認的配置項,并可能在稍后決定是否將當前的配置項自動保存為配置文件(這樣的話下一次文件就肯定存在了)。現在讓我們假定我們捕獲到了一個IsADirectoryError或是PermissionError錯誤,在這種情況下,我們可能不想讓程序繼續執行,我們仍然能夠使用默認的配置參數,但是隨后我們就不能保存文件了。也有可能用戶希望使用自定義的配置項,所以這樣的話就不能使用默認配置項了。所以我們這時候可能需要立即告知用戶并停止當前程序。也有可能我們并不想在這么一小塊代碼中做這么多的事情,而是讓應用層面的部分去關心它,所以我們也可能讓這個錯誤浮到頂層,讓頂層的業務邏輯去處理。

Python 2 idioms document文檔中也提到了一個簡單的例子:如果在我們的代碼中出現了一個簡單的拼寫錯誤而導致程序錯誤。在這種情況下因為我們捕獲所有的異常,所以我們將會捕獲到名稱錯誤(NameErrors)以及語法錯誤(SyntaxErrors)。兩者都是常見的錯誤,并且兩者都是不希望出現在我們最終代碼中的。但是因為我們什么異常都逮,當異常發生時我們將無法區分具體的錯誤類型并且無法進行調試。

但是也存在這樣一些并未預先準備的危險異常,諸如系統錯誤(SystemError)就很少發生以至于我們根本沒有準備;這些異常通常需要更復雜的處理操作,這些操作通常可能會要求我們停止當前的工作。

在任何情況下,通過局部代碼實現對所有異常的處理基本上都是不可能的,所以你應該有針對性的去處理那些經過準備的特定異常。有些人曾建議至少應該明確指明基本異常(Exception)這樣的不包含諸如系統退出(SystemExit)和鍵盤中斷(KeyboardInterrupt)這樣設計用來終止應用程序的異常。但是我想說這樣還是不夠明確,并且我個人認為只有在一個地方才能僅僅只捕獲Exception或是任何類型的異常,那就是一個單獨的,應用程序層面的異常捕獲器,并且這個捕獲器唯一的任務就是去捕獲任何可能出現的未經準備的漏網異常。這樣的話我們仍然能夠保留意外發生異常的相關信息作為進一步的代碼擴展的依據(讓然如果我們能讓程序恢復的話),這樣下一次我們就能夠把這個異常在合適的地方顯式地指定出來或是指導我們撰寫測試用例以保證錯誤不再發生(當然了,這一切還是要當我們對特定異常有所準備時,沒有準備的異常還是會溜掉)。

在異常處理的邏輯中,不要什么都不做

當顯式地捕獲到有限的幾個異常之后,很多時候我們的確不需要做什么特別的處理。這種情況下,except SomeSpecificException: pass這么做是可以的。但是大多數情況下,我們還是需要一些與錯誤恢復相關的代碼,例如重復嘗試的動作以及設置默認值。

同時也考慮到其它情況,例如如果我們的代碼結構已經確定了必須不斷嘗試直到成功才能繼續,那么什么也不做就已經夠了。具體來說,我們需要用戶輸入一個數字,因為我們知道用戶可能不會按照我們設計的那樣做,所以我們會將這個部分放入一個循環,比如像這樣:
 

?
1
2
3
4
5
6
def askForNumber ():
  while True:
    try:
      return int(input('Please enter a number: '))
    except ValueError:
      pass

因為我們會不斷讓用戶輸入直到沒有異常拋出為止,這種情況下我們就不需要在except塊中做其他任何特別的操作,這樣就夠了。當然了,有人會說你至少應該讓用戶得到一些錯誤信息以明確他們為什么在此被反復地要求輸入。

在其他一些情況下,except塊中的passing語句顯示了我們并沒有真正的對異常做好準備。除非是一些簡單的異常(諸如值錯誤ValueError或類型錯誤TypeError)我們都應該做一些操作,原因也很明顯,避免簡單的passing。如果真沒什么可做的(如果你真的確定),那么考慮加一些解釋性的注釋在此;否則,請擴展except塊添加一些恢復性的代碼。

except: pass

最不能容忍的就是兩者的結合了。這意味著我們自愿捕獲任何異常(包括那些我們沒有準備的)并且對它們視而不見。你應該至少在日志中記錄一下這個錯誤并且向上提出來終止當前程序(我就不信出現MemoryError你的程序依然能正常運行)。放過這些異常將會使程序在錯誤的軌道上繼續運行下去并且丟掉了關鍵的錯誤信息從而使得錯誤不易被發現,特別是當不是你親自遇到它的時候。

所以,底線是去捕獲那些經過準備的特定異常;其他發生的異常要么是等著你去修復的錯誤,要么是你無法處理的。當真的沒有什么可做的時候放過某些特定異常是可以的,其他情況如果這么做就只能被認為是怠工或偷懶了。你的確應該去處理這些異常的。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚洲欧美久久一区二区 | 四虎影库紧急大通知 | 91视频破解版 | 午夜AV内射一区二区三区红桃视 | 全肉一女n男np高h双龙养成 | 国产成人一区二区三区在线视频 | 私人黄色影院 | 亚洲H成年动漫在线观看不卡 | 亚洲人成综合在线播放 | 国产亚洲精品综合在线网址 | 国产精品亚洲精品观看不卡 | 男人躁女人p | 成人精品视频一区二区在线 | t66y地址一地址二地址三 | 91精品国产在线 | 欧美日韩在线成人看片a | 四虎麻豆国产精品 | 青草青青在线视频观看 | 紧身裙女教师miad711在线 | 四虎影视e456fcom四虎影视 | 91精品国产综合久久香蕉 | 全程粗语对白视频videos | 日本三级免费观看 | 亚洲va欧美va国产va天堂影 | 日本不卡在线视频高清免费 | 国产成人一区二区三区小说 | 2020国产精品永久在线观看 | 91国内精品久久久久怡红院 | 免费精品在线 | 菠萝视频在线完整版 | 嫩草蜜桃 | 国产综合图区 | 日本在线观看a | 国产精品国产国产aⅴ | 成人国产精品一级毛片视频 | 亚洲 欧美 国产 视频二区 | 亚洲国产高清视频 | 全黄h全肉细节文在线观看 全彩成人18h漫画 | 欧美午夜视频一区二区 | 亚洲成色 | 91精品国产91久久久久 |