Python 中的異常處理
阿新 • • 發佈:2021-06-10
1 異常處理
異常即是一個事件,該事件會在程式執行過程中發生,會讓程式崩潰,中止執行;為了防止程式中斷,增加程式的健壯性,可以做一些預處理,當Python指令碼發生異常時可以捕獲處理它。1.1 常見異常
AttributeError 試圖訪問一個物件沒有的樹形,比如foo.x,但是foo沒有屬性x
IOError 輸入/輸出異常;基本上是無法開啟檔案
ImportError 無法引入模組或包;基本上是路徑問題或名稱錯誤
IndentationError 語法錯誤(的子類) ;程式碼沒有正確對齊
IndexError 下標索引超出序列邊界,比如當x只有三個元素,卻試圖訪問x[5]
KeyError 試圖訪問字典裡不存在的鍵
KeyboardInterrupt Ctrl +C被按下
NameError 使用一個還未被賦予物件的變數
SyntaxError Python程式碼非法,程式碼不能編譯(個人認為這是語法錯誤,寫錯了)
TypeError 傳入物件型別與要求的不符合
UnboundLocalError 試圖訪問一個還未被設定的區域性變數,基本上是由於另有一個同名的全域性變數,
導致你以為正在訪問它
ValueError 傳入一個呼叫者不期望的值,即使值的型別是正確的
Python的異常處理能力是很強大的,它有很多內建異常,可向使用者準確反饋出錯資訊,在Python中,異常也是物件,可對它進行操作。BaseException是所有內建異常的基類,但使用者定義的類並不直接繼承BaseException,所有的異常類都是從Exception繼承,且都在exceptions模組中定義。Python自動將所有異常名稱放在內建名稱空間中,所以程式不必匯入exceptions模組即可使用異常。一旦引發並且沒有捕捉SystemExit異常,程式執行就會終止。1.2 異常處理語法結構
try:
<語句> #執行別的程式碼
except <異常名稱>:
<語句> #如果在try部份引發了'name'異常
except (<異常A>,<異常B>):
<語句> #如果引發了'name'異常,獲得附加的資料
else:
<語句> #如果沒有引發異常,則執行else中的語句
finally:
<語句> # 無論是否發生異常都將執行finally程式碼
raise
1.3 異常捕獲場景
如果我們已經知道這種型別的錯誤,那麼就可以通過一個異常來捕捉這個錯誤。我們可以通過try...except 來預知處理這個異常。
1.3.1 指定單個異常
只能用來處理指定的異常情況,如果未捕獲到異常,則報錯。try:
open("test.text")
except FileNotFoundError as e: # as+變數名:重新命名異常資訊
print("檔案操作失敗,原因:", e)
# 執行結果:
檔案操作失敗,原因: [Errno 2] No such file or directory: 'test.text'
1.3.2 捕獲多個異常
一般建議捕獲可能出現的多個異常(按照先子類後父類的順序),並且針對性的寫出多個異常處理程式碼。異常可以分別處理,或者放在一行處理。 方法一:多分支def dev(a, b):
try:
c = float(a)/float(b)
except ValueError as e: # as+變數名:重新命名異常資訊
print("字串不能做除法,具體異常如下:", e)
except ZeroDivisionError as e:
print("0不能作為除數,具體異常資訊:", e)
dev(2, 0)
異常處理規則:
①第一個except中定義的異常與引發的異常匹配,則執行該except中的語句;
②引發的異常不匹配第一個except,則會搜尋第二個except,允許編寫的except數量沒有限制
③所有的except都不匹配,則異常未捕獲就會丟擲
方法二:一行except同時處理多個異常
def dev(a, b):
try:
c = float(a)/float(b)
except (ValueError, ZeroDivisionError) as e: # as+變數名:重新命名異常資訊
print("具體異常如下:", e)
dev(2, 0)
1.3.3 萬能異常
在python的異常中,有一個萬能異常:Exception,它可以捕獲任意異常。它是一把雙刃劍,有利有弊,我們要視情況使用,優點是什麼異常都會被捕獲,但是會導致我們不清楚是哪種型別的異常資訊,因此可與多分支結合使用,需要注意的是,萬能異常一定要放在最後,否則就沒有意義了。def dev(a, b):
try:
c = float(a)/float(b)
except Exception as e: # as+變數名:重新命名異常資訊
print("具體異常如下:", e)
dev(2, 0)
1.3.4 異常中的else
如果判斷完沒有某些異常之後還想做其他事,就可以使用下面這樣的else語句,else下的語句是隻有無異常時才會執行,否則不執行。else和finally是可選的,可能會有0個或多個except,但是,如果出現一個else的話,必須有至少一個except。def dev(a, b):
try:
c = float(a)/float(b)
except Exception as e: # as+變數名:重新命名異常資訊
print("具體異常如下:", e)
else:
print("無異常")
dev(2, 0)
1.3.5 異常中的finally
try...finally...語句無論是否發生異常都將會執行最後的程式碼。try:
<語句>
finally:
關閉瀏覽器
driver.quit()
1.4 異常的其他用途
捕獲異常不僅是為了防止程式中斷,還可以通過異常進行場景處理,如以下程式碼,通過捕獲異常IndexError取代列表長度判斷,減少程式碼量。# 題目:給你一個非空陣列,返回此陣列中第三大的數 。如果不存在,則返回陣列中最大的數。
def ThirdNum(num_list):
if num_list:
try:
return sorted(list(set(num_list), reverse=False)[2]
except IndexError:
return sorted(num_list, reverse=True)[0]
else:
print("傳入陣列不能為空")
if __name__ == '__main__':
alist = [2, 9]
print(ThirdNum(alist))