1. 程式人生 > >Python 之異常處理機制

Python 之異常處理機制

python在程式執行出現錯誤時時有相應的反應機制 ,我們可以針對不同的錯誤做出不同的響應

1 list1 = ['a','b','c']
2 print(list1[4])         #>>>IndexError: list index out of range
3 a = {"name":"Jack",
4      "age":22}
5 print(a["sex"])         #KeyError: 'sex'

例子中分別指出了兩個錯誤:IndexError和KeyError。如果我們想對程式中是否出現了這種錯誤,可以抓取出來。下面我們就針對這兩種錯誤舉例

 1 list1 = ['a','b','c']
 2 a = {"name":"Jack",
 3      "age":22}
 4 try:
 5     list1[2]
 6     a["sex"]            #這裡是有錯的!
 7 except IndexError as e:
 8     print("列表操作錯誤",e)
 9 except KeyError as e:
10     print("沒有這個key",e)

當try裡的程式碼出現錯誤的話,通過except把錯誤獲取

 

C:\Users\Aaron\Anaconda3\python.exe D:/python/week7/錯誤處理.py
沒有這個key 
'sex'
執行結果

 

這樣就會得到了,可是如果會有很多種錯誤的話,每種錯誤都加個except也太麻煩了!就可以這麼寫:

1 list1 = ['a','b','c']
2 a = {"name":"Jack",
3      "age":22}
4 try:
5     list1[5]             #這裡是有錯的!
6     a["sex"]             #這裡是有錯的!
7 except (IndexError,KeyError) as e:
8     print("錯誤!",e)

但又出了個問題,用這種寫法的話當出現錯誤,不能很好的顯示錯誤的種類例子中兩個條件都是錯誤的,只能顯示成

C:\Users\Aaron\Anaconda3\python.exe D:/python/week7/錯誤處理.py
錯誤! list index out of range
執行結果

所以這種方式是不推薦使用的!可是既然可以這麼寫,是不是有其他的作用呢?這時需要一個另外的用法——萬能異常:Exception,可以把所有的錯誤抓取。這時候就可以做排除已知錯誤外的所有未知錯誤。

 1 list1 = ['a','b','c']
 2 a = {"name":"Jack",
 3      "age":22}
 4 try:
 5     list1[2]
 6     a["name"]
 7     open("沒有這個檔案.txt")#這裡是有錯的!
 8 except IndexError as e:
 9     print("列表操作錯誤",e)
10 except KeyError as e:
11     print("沒有這個key",e)
12 except Exception as e:
13     print("未知錯誤",e)

在前面的錯誤型別都沒有的話,可以顯示最後的錯誤!

C:\Users\Aaron\Anaconda3\python.exe D:/python/week7/錯誤處理.py
未知錯誤 [Errno 2] No such file or directory: '沒有這個檔案.txt'
執行結果

總而言之,一般的異常處理結構是這樣的:

 1 list1 = ['a','b','c']
 2 a = {"name":"Jack",
 3      "age":22}
 4 try:
 5     list1[2]
 6     a["name"]
 7     open("沒有這個檔案.txt")#這裡是有錯的!
 8 except (IndexError,KeyError) as e:
 9     print("列表操作錯誤",e)
10 except KeyError as e:
11     print("沒有這個key",e)
12 except Exception as e:
13     print("未知錯誤",e)
14 else:
15     print("一切正常")
16 finally:
17     print("無論是否發生異常,這裡的程式碼都要執行")

我們現在看一看常用的異常程式碼

AttributeError 試圖訪問一個物件沒有的屬性,比如foo.x,但是foo沒有屬性x
IOError 輸入/輸出異常;基本上是無法開啟檔案
ImportError 無法引入模組或包;基本上是路徑問題或名稱錯誤
IndentationError 語法錯誤(的子類) ;程式碼沒有正確對齊
IndexError 下標索引超出序列邊界,比如當x只有三個元素,卻試圖訪問x[5]
KeyError 試圖訪問字典裡不存在的鍵
KeyboardInterrupt Ctrl+C被按下
NameError 使用一個還未被賦予物件的變數
SyntaxError Python程式碼非法,程式碼不能編譯(個人認為這是語法錯誤,寫錯了)
TypeError 傳入物件型別與要求的不符合
UnboundLocalError 試圖訪問一個還未被設定的區域性變數,基本上是由於另有一個同名的全域性變數,
導致你以為正在訪問它
ValueError 傳入一個呼叫者不期望的值,即使值的型別是正確的
常用異常

對了,還有一種異常處理在程式除錯中可以用到:觸發異常:

1 try:
2     raise KeyError
3 except KeyError as e:
4     print("沒有這個Key",e)

在try中加入 raise,可以通過程式碼直接觸發異常

最後,還有一種異常的用法:自定義異常

1 class concect_Error(Exception):
2     def __init__(self,msg):
3         self.msg = msg
4 try:
5     raise concect_Error("資料庫連線失敗")
6 except concect_Error as e:
7     print(e)

要注意的是,在定義錯誤的類中,一定要繼承Exception的屬性。自定義的類是屬於Exception這個大類的!