零基礎學Python:異常檢測及處理

前言python

本文的文字及圖片來源於網絡,僅供學習、交流使用,不具備任何商業用途,若有問題請及時聯繫咱們以做處理。網絡

PS:若有須要Python學習資料的小夥伴能夠點擊下方連接自行獲取框架

Python免費學習資料、代碼以及交流解答點擊便可加入函數


 

1.異常

在運行或編寫一個程序時常會遇到錯誤異常,這時 python 會給你一個錯誤提示類名,告訴出現了什麼樣的問題(Python是面嚮對象語言,因此程序拋出的異常也是類)。能很好的理解這些錯誤提示類名所表明的意思,能夠幫助你在最快的時間內找到問題所在,從而解決程序上的問題是很是有幫助的。學習

Python中的異常

在先前的一些章節裏你已經執行了一些代碼,你必定遇到了程序「崩潰」或因未解決的錯誤而終止的狀況。你會看到「跟蹤記錄(traceback)」消息以及隨後解釋器向你提供的信息,包括錯誤的名稱、緣由和發生錯誤的行號。無論你是經過 Python 解釋器執行仍是標準的腳本執行,全部的錯誤都符合類似的格式,這提供了一個一致的錯誤接口。全部錯誤,不管是語意上的仍是邏輯上的,都是因爲和 Python 解釋器不相容致使的,其後果就是引起異常。ui

咱們來看幾個異常的例子。操作系統

NameError

嘗試訪問一個未申明的變量3d


NameError 表示咱們訪問了一個沒有初始化的變量。對象

 

在 Python 解釋器的符號表沒有找到那個那個被調用的變量。任何可訪問的變量必須先定義才能使用,訪問變量須要由解釋器進行搜索,若是請求的名字沒有在任何名稱空間裏找到,那麼將會生成一個NameError 異常。blog

ZeroDivisionError

除數爲零


任何數值被零除都會致使一個 ZeroDivisionError 異常。

 

SyntaxError

Python解釋器語法錯誤


SyntaxError 表明Python代碼中有一個不正確的結構,在它改正以前程序沒法執行。

 

IndexError

請求的索引超出序列範圍


IndexError 在你嘗試使用一個超出範圍的值索引序列時引起。

 

KeyError

請求一個不存在的字典關鍵字


映射對象,例如字典,是依靠關鍵字(key)訪問數據值的。若是使用錯誤的或是不存在的鍵請求字典就會引起一個KeyError異常。

 

IOError

操做的文件不存在


相似嘗試打開一個不存在的磁盤文件一類的操做會引起一個操做系統輸入/輸出(I/O)錯誤。任何類型的I/O錯誤都會引起IOError異常。

 

AttributeError

嘗試訪問未知的對象屬性


在咱們的例子中,咱們在 myInst.bar 儲存了一個值,也就是實例 mylnst 的 bar 屬性。屬性被定義後,咱們可使用熟悉的點/屬性操做符訪問它,但若是是沒有定義屬性,例如咱們訪問 foo 屬性,將致使一個 AttributeError 異常。

 

檢測和處理異常

異常能夠經過try語句來檢測。任何在try語句塊裏的代碼都會被監測,檢查有無異常發生。

try語句有兩種主要形式:try-except和try-finally。這兩個語句是互斥的,也就是說你只能使用其中的一種。一個try語句能夠對應一個或多個except子句,但只能對應一個finally子句,或是一個try-except-finally複合語句。

可使用try-except語句檢測和處理異常。也能夠添加一個可選的else子句處理沒有探測到異常的執行的代碼。而try-finally只容許檢測異常並作一些必要的清除工做(不管發生錯誤與否),沒有任何異常處理設施。正如你想像的,複合語句二者均可以作到。

try-except語句

try-except語句(以及其更復雜的形式)定義了進行異常監控的一段代碼,而且提供了處理異常的機制。

最多見的try-except語句語法以下所示。它由try塊和except塊(try_suite和except_suite)組成,也能夠有一個可選的錯誤緣由。

 

 

用一個例子說明這一切是如何工做的。將使用上邊的IOError例子,把代碼封裝在try-except裏,讓代碼更健壯:

 


若是輸入的是一個數字字符串,代碼運行時彷佛沒有遇到任何錯誤。當嘗試轉化一個非數字字符時仍然發生了錯誤。爲了防止錯誤發生而致使的程序中止,可使用 try...except 語句捕捉錯誤。

在程序運行時,解釋器嘗試執行try塊裏的全部代碼,若是代碼塊完成後沒有異常發生,執行流就會忽略except語句繼續執行。而當except語句所指定的異常發生後,咱們獲取了錯誤的緣由,控制流當即跳轉到對應的處理器(try子句的剩餘語句將被忽略)。

 

 

能夠只捕獲 ValueError 異常。任何其餘異常不會被咱們指定的處理器捕獲。舉例說,若是你要捕獲一個特定的異常,你必須加入一個特定的異常處理器。

try語句塊中異常發生點後的剩餘語句永遠不會到達(因此也永遠不會執行)。一旦一個異常被引起,就必須決定控制流下一步到達的位置。剩餘代碼將被忽略,解釋器將搜索處理器,一旦找到,就開始執行處理器中的代碼。

若是沒有找到合適的處理器,那麼異常就向上移交給調用者去處理,這意味着堆棧框架當即回到以前的那個。若是在上層調用者也沒找到對應處理器,該異常會繼續被向上移交,直到找到合適處理器。若是到達最頂層仍然沒有找到對應處理器,那麼就認爲這個異常是未處理的,Python解釋器會顯示出跟蹤記錄,而後退出。

帶有多個 except 的 try 語句

在本章的前邊,咱們已經介紹了except的基本語法:

 

 

這種格式的except語句指定檢測名爲Exception的異常。你能夠把多個except語句鏈接在一塊兒,處理一個try塊中可能發生的多種異常,以下所示:

 


一樣,首先嚐試執行try子句,若是沒有錯誤,忽略全部的except從句繼續執行。若是發生異常,解釋器將在這一串處理器(except子句)中查找匹配的異常若是找到對應的處理器,執行流將跳轉到這裏。

咱們的safe_float()函數已經能夠檢測到指定的異常了。更聰明的代碼可以處理好每一種異常。這就須要多個except語句,每一個except語句對應一種異常類型。Python支持把except語句串連使用咱們將分別爲每一個異常類型分別建立對應的錯誤信息,用戶能夠獲得更詳細的關於錯誤的信息:

 

 

使用錯誤的參數調用這個函數,咱們獲得下面的輸出結果:

 

finally子句

finally 子句是不管異常是否發生,是否捕捉都會執行的一段代碼。你能夠將 finally 僅僅配合 try 一塊兒使用,也能夠和 try-except (else也是可選的)一塊兒使用。獨立的 try-finally 將會在下一章介紹,咱們稍後再來研究。

從Python 2.5開始,你能夠用finally子句(再一次)與try-except或try-except-else—起使用。之因此說是「再一次」是由於不管你相信與否,這並非一個新的特性。回顧Python初期,這個特性早已存在,可是在Python 0.9.6(1992 4月)中被移除。那時,這樣能夠簡化字節碼的生成,並方便解析,另外vanRossum認爲一個標準化的try-except(-else)-finally不管如何不會太流行。然而,十年時間改變了一切!

下面是try-except-else-finally語法的示例:

 

 

finally都是可選的。A、B、C是程序(代碼塊)。程序會按預期的順序執行。(注意:可能的順序是AD[正常]或AD[異常])。不管異常發生在Α、Β和/或C都將執行finally塊。舊式寫法依然有效,因此沒有向後兼容的問題。

總結

1.只處理你知道的異常,避免捕獲全部異常而後吞掉它們。2.拋出的異常應該說明緣由,有時候你知道異常類型也猜不出因此然。3.避免在 except 語句塊中幹一些沒意義的事情,捕獲異常也是須要成本的。4.不要使用異常來控制流程,那樣你的程序會無比難懂和難維護。5.若是有須要,切記使用 finally 來釋放資源。6.若是有須要,請不要忘記在處理異常後作清理工做或者回滾操做。

相關文章
相關標籤/搜索