1. 程式人生 > >小白學 Python(19):基礎異常處理

小白學 Python(19):基礎異常處理

人生苦短,我選Python

前文傳送門

小白學 Python(1):開篇

小白學 Python(2):基礎資料型別(上)

小白學 Python(3):基礎資料型別(下)

小白學 Python(4):變數基礎操作

小白學 Python(5):基礎運算子(上)

小白學 Python(6):基礎運算子(下)

小白學 Python(7):基礎流程控制(上)

小白學 Python(8):基礎流程控制(下)

小白學 Python(9):基礎資料結構(列表)(上)

小白學 Python(10):基礎資料結構(列表)(下)

小白學 Python(11):基礎資料結構(元組)

小白學 Python(12):基礎資料結構(字典)(上)

小白學 Python(13):基礎資料結構(字典)(下)

小白學 Python(14):基礎資料結構(集合)(上)

小白學 Python(15):基礎資料結構(集合)(下)

小白學 Python(16):基礎資料型別(函式)(上)

小白學 Python(17):基礎資料型別(函式)(下)

小白學 Python(18):基礎檔案操作

前面我們已經寫了這麼多示例程式碼了,對於報錯資訊各位同學可能都已經司空見慣了,今天我們就來聊一下報錯資訊的處理。

首先,程式在執行的過程中,產生了異常,這時,我們可能會有兩種想法,第一種是針對這個異常做某些特殊的處理來進行程式的降級處理;第二種是希望程式忽略這個異常繼續執行下去,這個異常可能並不干擾主邏輯的執行。

那這個時候我們怎麼辦呢?

有程式設計經驗的同學馬上就想到了,那我們去 try 它啊,在 Python 中,我們同樣可以去 try 它,從字面意思上理解就已經非常清晰明確了,以下的內容是要嘗試執行的。

語法:

try:
    ...(可能產生異常的程式碼)
except:
    ...(產生異常後的處理程式碼)

但是,還會有一種情況,不管上面的程式碼有沒有出錯,有一部分程式碼我們總希望它能執行,這時,我們可以新增另一個關鍵字 finally

從字面意思可以就可以看出來,這個是最後要執行的意思。

語法:

try:
    ...(可能產生異常的程式碼)
except:
    ...(產生異常後的處理程式碼)
finally:
    ...(一定要執行的程式碼)

下面開始我們今天的程式碼演示。

我們先擬定一個場景,我們定義一個除法函式,如果除數不為 0 ,是可以正常返回值的,如果除數為 0 ,那麼整個程式肯定會直接異常報錯。

def division(x, y):
    try:
        return x / y
    except:
        print('程式報錯啦!!!')
        return None

print(division(15, 5))

輸出結果如下:

3.0

這時程式是可以正常輸出的,這時我們修改一下呼叫的引數,改為 division(15, 0) ,看下輸出結果:

程式報錯啦!!!
None

可以看到,這裡列印了我在程式中設定的 None ,並沒有之前的紅色的異常資訊丟擲。這裡的 except 會捕捉我們所有的異常資訊,但是,異常資訊也是有很多分類的,比如我們之前遇到過的訪問字典中不存在的 key 的異常 KeyError ,比如我們剛才捕捉到的 ZeroDivisionError 異常,還有也是我們之前遇到過的陣列下標越界的異常 IndexError

比如這裡的程式碼我可以捕捉更加詳細的異常資訊 ZeroDivisionError

def division1(x, y):
    try:
        return x / y
    except ZeroDivisionError:
        print('程式報錯啦!!!')
        return None

print(division1(15, 0))

輸出結果如下:

程式報錯啦!!!
None

那麼,看到這裡,你可能會有一個疑問,我們為什麼要對異常分類,直接抓取所有異常不是更方便麼?

當然,對於邏輯比較簡單的程式,直接捕捉所有異常是更方便的,但是在某些特定的業務場景下,一段程式可能會丟擲多種異常,我們希望根據異常種類的不同,定製不同的解決方案,至少我們知道當前的程式是丟擲了什麼異常,這時,程式異常分類就顯得尤為重要。

我們這裡演示一下,如果我們輸出的值不是數字,是字串的話。。。。

def division2(x, y):
    try:
        return x / y
    except ZeroDivisionError:
        print('您輸出的除數為 0 !!!')
        return None
    except TypeError:
        print('您輸出的引數型別非法!!!')
        return None

print(division2('python', 0))

輸出結果如下:

您輸出的引數型別非法!!!
None

對的,你沒有看錯,異常資訊是能捕捉多個的,是可以並排寫的。至於先丟擲那個,就要看那個異常先發生了。

因為示例程式碼的邏輯過於簡單,異常丟擲順序無法演示,請各位同學見諒(li zhi qi zhuang)。

上面我們還提到了 finally ,我們接著來演示 finally 這個關鍵字的使用。

def division3(x, y):
    try:
        return x / y
    except ZeroDivisionError:
        print('您輸出的除數為 0 !!!')
        return None
    except TypeError:
        print('您輸出的引數型別非法!!!')
        return None
    finally:
        print('你一定能看到我!!!')

print(division3(15, 3))
print(division3('python', 0))

可以看到,這裡我使用有異常和正常無任何問題的資料進行測試,結果如下:

你一定能看到我!!!
5.0
您輸出的引數型別非法!!!
你一定能看到我!!!
None

確實, finally 中的內容是能正常列印的,這裡多提一句,這裡經常的使用方式是來關閉一些 I/O 讀寫操作或者一些外部連線,如資料庫、快取服務等。

今天的內容就到這裡,各位同學請回去自行嘗試。

示例程式碼

本系列的所有程式碼小編都會放在程式碼管理倉庫 Github 和 Gitee 上,方便大家取用。

示例程式碼-Github

示例程式碼-Gi