python之異常處理 Python之異常處理

2021-10-13 06:50:04 字數 4054 閱讀 2018

異常物件

請大家執行如下**

a = 100/0

print(a)

就會發現直譯器顯示如下的錯誤提示

traceback (most recent call last): file "*********x.py", line 1, in

a = 100/0

zerodivisionerror: division by zero

大家要學會看直譯器的報錯。

這就是直譯器向我們報告, 有乙個 zerodivisionerror 錯誤物件 或者說 異常物件 產生了。

這個 zerodivisionerror 物件 代表的是乙個除以0 的異常。 我們知道0是不能作為除數的。

因為這個問題,直譯器沒有辦法繼續執行後面的**了。所以程式就此結束執行了。

zerodivisionerror就是乙個異常物件的類,繼承自標準庫裡面的 exception 類。

python標準庫中還有很多其他的異常類 都是繼承自標準庫裡面的 exception 類,代表各種不同型別的錯誤。

大家可以在命令列視窗 執行 python 直譯器互動命令列,分別輸入如下**:

***x

會產生 nameerror,表示***x沒有定義

dict1 = print(dict1[2])

會產生 keyerror,表示該字典沒有key為2的元素

import ***x

會產生 modulenotfounderror,表示找不到***x這樣的模組

捕獲異常

直譯器執行**過程中,如果發生異常,就會導致直譯器沒法繼續按照正常流程往下執行**,所以直譯器會結束當前執行緒的執行。

如果執行的程式是個單執行緒的程式,整個程式執行就會結束了。

如果我們在編碼的時候,就預料到了某些**執行時可能出現某些異常,就可以使用 try...except... 這樣的方法來捕獲和處理異常。

比如,我們要開發程式,實現乙個把使用者輸入的身高從英呎換算成公尺,如下所示

while true:

miles = input('請輸入英里數:')

km = int(miles) * 1.609344

print(f'等於公里')

編寫這段**的時候, 我們就可以預料到,可能使用者會輸入非數字的字元,用int轉化就會出錯了,導致整個程式就退出了。

這時,我們就可以這樣寫

while true:

try:

miles = input('請輸入英里數:')

km = int(miles) * 1.609344

print(f'等於公里')

except valueerror:

print('你輸入了非數字字元')

try 下面縮排的**出現異常時,直譯器會結束 try中 後續**的執行,並檢查這個異常的型別是否匹配後面的except 語句中宣告的型別。

如果匹配上,就認為該異常是預先有對應的處理方案的,就執行匹配的except下面縮排的**。從而不會結束當前執行緒。上面的例子中,執行 try 下面縮排的**時,如果使用者輸入了 hello 這樣的非數字, 就會在這行語句處

km = int(miles) * 1.609344

產生 valueerror 型別的異常, 直譯器就會去檢視後面的 except 語句是否宣告了對 valueerror 異常的處理。

發現有, 就會執行後面縮排的**。也就是這句**

print('你輸入了非數字字元')

except 後面縮排的** 就是對這種型別錯誤 的一種處理。

既然程式已經知道如何處理這種問題, 就不需要結束執行,只需要執行完 處理**後, 進行原來正常的執行流程。

在這裡,就是繼續 while true 迴圈。

如果我們開發程式的時候,估計某個**段中可能出現好幾種型別的異常,可以使用多個except **段,分別捕獲多種型別的異常,如下

try:

choice = input('輸入你的選擇:')

if choice == '1':

100/0

elif choice == '2':

[2]except zerodivisionerror: print ('出現 zerodivisionerror') except indexerror : print ('出現 indexerror')

如果 輸入』1』, 則會產生 zerodivisionerror 異常, 就會被 except zerodivisionerror 捕獲,執行對應的**

print ('出現 zerodivisionerror')

如果 輸入』2』, 則會產生 indexerror 異常, 就會被 except indexerror 捕獲,執行對應的**

print ('出現 indexerror')

獲取異常物件

我們使用except 語句匹配異常型別的時候, 可以使用as關鍵字,後面加乙個變數名,如下所示:

try:

100/0

except zerodivisionerror as e:

print (f'異常物件資訊:')

這樣,執行**的時候,當try中的語句產生異常物件時,就會 把產生的異常物件賦值給as後的變數。

上面的**,執行輸出

異常物件資訊:division by zero

產生的異常物件賦值給了變數 e。

這樣我們就可以在後續的**中得到產生的異常物件的資訊。

匹配所有異常

如果我們在寫一段**的時候,不知道這段**會丟擲什麼樣的異常,並且我們不希望程式因為異常而中止。

這時我們可以匹配所有型別的異常,這樣任何型別的異常發生都不會終止程式了。 如下:

try:

100/0

except exception as e:

print('未知異常:', e)

因為所有的異常都是 exception 的子類。 所以 exception能匹配所有型別的異常。

except 為空,也可以匹配所有型別的異常,而且可以通過traceback庫,顯示異常的資訊和異常產生處的函式呼叫棧的資訊,如下

import traceback

try:

100/0

except:

print(traceback.format_exc())

上面的**會列印出導致異常的詳細的函式呼叫棧的資訊,如下

traceback (most recent call last):

file "***x/***.py", line 4, in

100/0

zerodivisionerror: division by zero

自定義異常

異常型別都是 繼承自exception的類,表示各種型別的錯誤。

我們也可以自己定義異常,比如我們寫乙個使用者註冊的函式, 要求使用者輸入的**號碼只能是中國的**號碼,並且**號碼中不能有非數字字元。

可以定義下面這兩種異常型別:

# 異常物件,代表**號碼有錯誤的字元

class invalidcharerror(exception):

pass

# 異常物件,代表**號碼非中國號碼

class notchinatelerror(exception):

pass

定義了上面的異常,當使用者輸入**號碼時,出現相應錯誤的時候,我們就可以使用raise 關鍵字來丟擲對應的自定義異常

def register():

tel = input('請註冊您的**號碼:')

# 如果有非數字字元

if not tel.isdigit():

raise invalidcharerror

# 如果不是以86開頭,則不是中國號碼

if not tel.startswith('86'):

raise notchinatelerror

return tel

try:

ret = register()

except invalidcharerror:

print('**號碼中有錯誤的字元')

except notchinatelerror:

print('非中國手機號碼')

Python之異常處理

在程式執行過程中影響程式正常執行的內容,稱為異常 nameerror print a indexerror 索引錯誤 li 1,2,3,4 print li 8 keyerror d dict a 1,b 2 print d f zerodivisionerror 除0錯誤 print 10 2 2...

Python之異常處理

try ret int input num 正常執行的 print ret except valueerror 捕捉錯誤 print 請輸入數字 try ret int input num 正常執行的 print ret except valueerror 捕捉錯誤 print 請輸入數字 exce...

Python之異常處理

異常處理結構 一.try except errortype as e 二.try except errortype as e finally 無論是否異常均會執行 三.try except exception 萬能異常捕獲 四.try 多分支結構 except errortype1 as e exc...