python中的異常處理常用方法
-
什麼是異常?
異常就是與正常情況不同,程式在執行過程中出現錯誤,導致無法執行完畢。異常其實就是程式碼執行過程中出錯。
-
常見的一些異常
-
AttributeError 試圖訪問一個物件沒有的屬性,比如foo.x,但是foo沒有屬性x
-
IOError 輸入/輸出異常;無法開啟檔案或無法讀寫
-
ImportError 無法引入模組或包;基本上是路徑問題或名稱錯誤
-
SyntaxError Python語法錯誤異常,程式碼不能編譯
-
IndentationError 縮排異常;程式碼沒有正確縮排
-
IndexError 下標索引超出序列邊界,比如當x只有三個元素,卻試圖訪問x[5]
-
KeyError 試圖訪問字典裡不存在的鍵
-
KeyboardInterrupt Ctrl+C被按下
-
NameError 使用一個還未被賦予物件的變數
-
TypeError 傳入物件型別與要求的不符合
-
UnboundLocalError 試圖訪問一個還未被設定的區域性變數,基本上是由於另有一個同名的全域性變數,
導致你以為正在訪問它 -
ValueError 傳入一個呼叫者不期望的值,即使值的型別是正確的
-
-
異常組成的三個部分
追蹤資訊、異常型別、異常的值
異常可以由發生的時間不同分為兩類:
-
語法檢測異常:直譯器解釋python語法時出現異常。必須在程式執行前改正。
-
執行時異常:已經通過了語法檢測,在執行期間發生異常。(邏輯錯誤)
幾種不同的異常處理的語法
1.如果錯誤發生的條件是可以預知的,我們需要用if進行處理:在錯誤發生之前進行預防
AGE=10 while True: age=input('>>: ').strip() if age.isdigit(): #只有在age為字串形式的整數時,下列程式碼才不會出錯,該條件是可預知的 age=int(age) if age == AGE:print('you got it') break else: print('you are wrong') break else: print('請輸入數字~~')
2.如果發生的錯誤條件是不可以預知的,我們就需要用到try......except的幾種用法:
在錯誤發生之後進行處理。
-
try.....except
try:
被檢測的程式碼塊
except 異常型別:
try中一旦檢測到異常,就執行這個位置的邏輯#這種方式只能用來處理指定的異常情況,如果非指定異常則無法處理。如果是非指定的異常型別會直接報錯。 try: print('starting') a = int('deng') # 這個位置很明顯是有邏輯錯誤的 print('ending') # 未執行這行程式碼 except ValueError: # 檢測到異常後執行了下面程式碼 print('發生了ValueError') ## starting 發生了ValueError
-
多分枝
try:
被檢測的程式碼塊
except 異常型別1:
try中一旦檢測到異常,就執行這個位置的邏輯except 異常型別2:
try中一旦檢測到異常,就執行這個位置的邏輯try: print('starting') l = [] print(l[1]) #這個位置發生了IndexError int('deng') #未執行 print('ending') except ValueError: #未執行 print('發生了ValueError') except IndexError: #檢測到異常,執行下面程式碼 print('發生了IndexError') ### starting 發生了IndexError
-
同一分支檢測多種異常
try:
被檢測的程式碼塊
except(多種異常型別):
try一旦檢測到異常,就執行這個位置的邏輯
try: print('starting') l = [] print(l[1]) #可以看出程式碼到這個位置就停止了 print('ending') int('deng') except (ValueError,IndexError): #只要檢測到異常就執行下面程式碼 print('發生了ValueError') ### starting 發生了ValueError
-
萬能異常1
try:
被檢測的程式碼塊
except Exception:
try一旦檢測到異常,就執行這個位置的邏輯
#這種方式儘量不要用,會導致程式既不報錯,也不會正常執行,無法定位報錯位置。 try: print('starting') l = [] print(l[1]) print('ending') int('deng') except Exception: print('going')
-
萬能異常2
try:
被檢測的程式碼塊
except Exception as e:
try一旦檢測到異常,就執行這個位置的邏輯
try: print('starting') l = [] print(l[1]) print('ending') int('deng') except Exception as e: #通過給異常取別名,來獲取異常物件,物件中包含錯誤資訊 print('going') print(e) print(type(e)) ### starting going list index out of range <class 'IndexError'>
我們可以看到e是一個類,所有的異常類都是Exception的子類。
萬能異常與多分枝異常處理區別。
1.如果你想要的效果是,無論出現什麼異常,我們統一丟棄,或者使用同一段程式碼邏輯去處理他們,那麼騷年,大膽的去做吧,只有一個Exception就足夠了。
2.如果你想要的效果是,對於不同的異常我們需要定製不同的處理邏輯,那就需要用到多分支了。 -
明確型別與萬能異常2合用
try:
被檢測的程式碼塊
except 異常型別1:
try中一旦檢測到異常,就執行這個位置的邏輯except 異常型別2:
try中一旦檢測到異常,就執行這個位置的邏輯except Exception as e:
try一旦檢測到異常,就執行這個位置的邏輯
#明確型別應該放在萬能型別前才能正常使用 try: print('starting') l = [] print(l[1]) print('ending') int('deng') except ValueError: print('值發生錯誤。。。') except ZeroDivisionError: print('被除數不能為0') except Exception as e: print('going')
-
try:
被檢測的程式碼塊
except 異常型別1:
try中一旦檢測到異常,就執行這個位置的邏輯except 異常型別2:
try中一旦檢測到異常,就執行這個位置的邏輯except Exception as e:
try一旦檢測到異常,就執行這個位置的邏輯
else:
程式碼體中沒有異常執行這個位置的邏輯
try: print('starting') l = [] print(l[1]) print('ending') int('deng') except ValueError: print('值發生錯誤。。。') except ZeroDivisionError: print('被除數不能為0') except Exception as e: print('going') else: print('這段程式碼沒有問題')
-
try:
被檢測的程式碼塊
except 異常型別1:
try中一旦檢測到異常,就執行這個位置的邏輯except 異常型別2:
try中一旦檢測到異常,就執行這個位置的邏輯except Exception as e:
try一旦檢測到異常,就執行這個位置的邏輯
else:
程式碼體中沒有異常執行這個位置的邏輯
finally:
程式碼體不管是否有異常,最終都執行該部分邏輯
try: print('starting') l = [] print(l[1]) print('ending') int('deng') except ValueError: print('值發生錯誤。。。') except ZeroDivisionError: print('被除數不能為0') except Exception as e: print('going') else: print('這段程式碼沒有問題') finally: print('這是備用方案~~') print('這是關閉檔案操作')
-
主動觸發丟擲異常
try:
raise TypeError('型別錯誤')
except Exception as e:
print(e)#自定義異常 class LoginException(Exception): pass def login(): name = input('name>>:').strip() pwd = input('password>>:').strip() if name == 'deng' and pwd == '123': print('login') else: raise LoginException('使用者名稱密碼錯誤!~') login()
-
斷言 assert
在程式中,有一段程式碼體,要執行必須保證某個條件必須成立,類似於if判斷,但是斷言不用將程式碼體縮排至其內部。
#使用if判斷 l = ['ming','deng'] if l: print('nihaoa ') #使用斷言 assert l print('nihaom') print(l[0])
總結:異常處理的作用
1:把錯誤處理和真正的工作分開來
2:程式碼更易組織,更清晰,複雜的工作任務更容易實現;
3:毫無疑問,更安全了,不至於由於一些小的疏忽而使程式意外崩潰了。