關於Python的異常捕獲和處理
程序運行過程中,一旦出現異常將會導致程序立即終止,異常以後的代碼全部都不會執行!
1 | 語法錯誤
指解析代碼時出現的錯誤。當代碼不符合Python 語法規則時,Python解釋器在解析時就會報出 SyntaxError 語法錯誤,與此同時還會明確指出最早探測到錯誤的語句。例如:
print "Hello,World!"
我們知道,Python 3.0已不再支持上面這種寫法,所以在運行時,解釋器會報如下錯誤:
SyntaxError: Missing parentheses in call to 'print'
語法錯誤多是開發者疏忽導致的,屬於真正意義上的錯誤,是解釋器無法容忍的,因此,隻有將程序中的所有語法錯誤全部糾正,程序才能執行。
2 | 運行時錯誤
運行時錯誤,即程序在語法上都是正確的,但在運行時發生瞭錯誤。例如:
a = 1/0
上面這句代碼的意思是“用 1 除以 0,並賦值給 a 。因為0 作除數是沒有意義的,所以運行後會產生如下錯誤:
Traceback (most recent call last): File "<pyshell#0>", line 1, in <module> 1/0 ZeroDivisionError: division by zero
3 |其他異常
以上運行輸出結果中,前兩段指明瞭錯誤的位置,最後一句表示出錯的類型。在 Python 中,把這種運行時產生錯誤的情況叫做異常(Exceptions)。
這種異常情況還有很多,常見的幾種異常情況如下表:
異常類型 | 含義 | 實例 |
AssertionError | 當 assert 關鍵字後的條件為假時,程序運行會停止並拋出此異常 |
>>> assert 1>0 >>> assert 1<0 AssertionError |
AttributeError | 當試圖訪問的對象屬性不存在時,拋出的異常 |
>>> s="hello" >>> s.len AttributeError: 'str' object has no attribute'len' |
IndexError | 索引超出序列范圍,會引發此異常 |
>>> s="hello" >>> s[5] IndexError: string index out of range |
KeyError | 字典中查找一個不存在的關鍵字時,引發此異常 |
>>> demo_dict={"age": 20} >>> demo_dict["name"] KeyError: 'name' |
NameError | 嘗試訪問一個未聲明的變量時,引發此異常 |
>>> hello NameError: name 'hello' is not defined |
TypeError | 不同類型數據之間的無效操作 |
>>> 1+"2" TypeError: unsupported operand type(s) for +: 'int' and 'str' |
ZeroDivisionError | 除法運算中除數為 0 引發此異常 |
>>> a = 1/0 ZeroDivisionError: division by zero |
4 | 異常處理
程序運行時出現異常,目的並不是讓我們的程序直接終止!Python是希望在出現異常時,我們可以編寫代碼來對異常進行處理!
Python 提供瞭try except語句捕獲並處理異常,該異常處理語句的基本語法結構如下:
try: # 可能產生異常的代碼塊 except [(Error1, Error2, ...) [as e]]: # 處理異常的代碼塊1 except [(Error3, Error4, ...) [as e]]: # 處理異常的代碼塊2
該格式中,[ ] 括起來的部分可以使用,也可以省略。其中各部分的含義如下:
- (Error1, Error2,…) 、(Error3, Error4,…):其中,Error1、Error2、Error3 和Error4 都是具體的異常類型。顯然,一個 except 塊可以同時處理多種異常。
- [as e]:作為可選參數,表示給異常類型起一個別名 e,這樣做的好處是方便在except 塊中調用異常類型(後續會用到)。
- [Exception]:作為可選參數,可以代指程序可能發生的所有異常情況,其通常用在最後一個 except 塊。
- 註:except 後面也可以不指定具體的異常名稱,這樣的話,表示要捕獲所有類型的異常。
另外,從 try except 的基本語法格式可以看出,try 代碼塊僅有一個,但except 代碼塊可以有多個,這是為瞭針對不同的異常類型提供不同的異常處理方式。當程序發生不同的意外情況時,會對應不同的異常類型,Python 解釋器就會根據該異常類型來決定使用哪個 except 塊來處理該異常。
try except 語句的執行流程如下:
1、首先執行 try 中的代碼塊,如果執行過程中出現異常,系統會自動生成一個異常類型,並將該異常提交給 Python 解釋器,此過程稱為捕獲異常。
2、當 Python 解釋器收到異常對象時,會尋找能處理該異常對象的 except 塊,如果找到合適的 except 塊,則把該異常對象交給該 except 塊處理,這個過程被稱為處理異常。如果 Python 解釋器找不到處理異常的 except 塊,則程序運行終止,Python 解釋器也將退出。
異常處理例子:
try: a = int(input("輸入被除數:")) b = int(input("輸入除數:")) c = a / b print("您輸入的兩個數相除的結果是:", c ) except (ValueError, ArithmeticError): print("程序發生瞭數字格式異常、算術異常之一") except : print("未知異常") print("程序繼續運行")
程序運行結果為:
輸入被除數:a程序發生瞭數字格式異常,算術異常之一程序繼續運行
上面程序中,第 6 行代碼使用瞭(ValueError, ArithmeticError)來指定所捕獲的異常類型,這就表明該 except 塊可以同時捕獲這 2 種類型的異常;第 8 行代碼隻有 except 關鍵字,並未指定具體要捕獲的異常類型,這種省略異常類的 except 語句也是合法的,它表示可捕獲所有類型的異常,一般會作為異常捕獲的最後一個 except 塊。除此之外,由於 try 塊中引發瞭異常,並被 except 塊成功捕獲,因此程序才可以繼續執行,才有瞭“程序繼續運行”的輸出結果。
通過在try塊後提供多個except塊可以無須在異常處理塊中使用if判斷異常類型,但依然可以針對不同的異常類型提供相應的處理邏輯,從而提供更細致、更有條理的異常處理邏輯。
事實上,不管程序代碼塊是否處於 try 塊中,甚至包括 except 塊中的代碼,隻要執行該代碼塊時出現瞭異常,系統總會自動生成一個 Error 對象。如果程序沒有為這段代碼定義任何的 except 塊,則 Python 解釋器無法找到處理該異常的 except 塊,程序就會停止運行;反之,如果程序發生異常,並且該異常經 try 捕獲並由 except 處理完成,則程序會繼續執行。
5 | 獲取特定異常的有關信息
每種異常類型都提供瞭如下幾個屬性和方法,通過調用它們,就可以獲取當前處理異常類型的相關信息:
- args:返回異常的錯誤編號和描述字符串;
- str(e):返回異常信息,但不包括異常信息的類型;
- repr(e):返回較全的異常信息,包括異常信息的類型。
try: result=20/int(input("請輸入除數:")) print(result) except ValueError: print("必須輸入整數") except ArithmeticError: print("算數錯誤,除數不能為 0") else: print("沒有出現異常") print("繼續運行")
程序運行結果為:
輸入被除數:210沒有出現異常繼續運行
6 |finally語句
Python 異常處理機制還提供瞭一個 finally 語句,用來為 try 塊中的程序做掃尾清理工作。
在整個異常處理機制中,finally 語句的功能是:無論 try 塊是否發生異常,最終都要進入 finally 語句,並執行其中的代碼塊。
finally 示例:
try: a=20/int(input("請輸入 a 的值:")) print(a) except: print("發生異常") else: print("執行 else 代碼塊") finally: print("執行 finally 代碼塊")
finally 代碼塊的強大還遠不止此,即便當 try 塊發生異常,且沒有合適和except 處理異常時,finally 塊中的代碼也會得到執行。
到此這篇關於關於Python的異常捕獲和處理的文章就介紹到這瞭,更多相關Python異常捕獲處理內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!