Python 之異常處理機制
阿新 • • 發佈:2018-12-11
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這個大類的!