『無為則無心』Python函式 — 39、Python中異常的傳播

繁華似錦Fighting發表於2022-01-26

1、異常的傳播

當在函式中出現異常時,如果在函式中對異常進行了處理,則異常不會再繼續傳播。如果函式中沒有對異常進行處理,則異常會繼續向函式呼叫者傳播。如果函式呼叫者處理了異常,則不再傳播,如果還沒有處理,則繼續向他的呼叫者傳播,直到傳遞到全域性作用域(主模組)如果依然沒有處理,則程式終止,並且顯示異常資訊到控制檯。所以異常的傳播我們也稱之為丟擲異常。

異常傳播示例如下:

def fn1():
    print('Hello fn')
    print(10/0)

def fn2():
    print('Hello fn2')
    fn()

def fn3():
    print('Hello fn3')
    fn2()

fn3()

輸出結果:

image

說明輸出結果:

當我們呼叫fn3()方法的時候,會先輸出Hello fn3,再向下執行呼叫fn2()方法,以此類推到fn1()方法中。可以看到上邊有三條輸出語句。

當執行到fn1()方法中print(10/0)語句,出現了ZeroDivisionError異常,而fn1()方法中沒有處理該異常,則向他的呼叫者丟擲這個異常,拋給了fn2()方法,以此類推,知道fn3()方法拋給了全域性作用域中的呼叫者,異常依然沒有被處理。

最後Python的直譯器會把這個異常顯示在控制檯中。

所以我們看到異常結果中,一行報錯,向上拋了好幾次。

例如:全域性作用域中的程式碼有異常沒有處理的話,就直接顯示在控制檯中了。

print(10 / 0)

輸出結果:

image

2、如何處理異常

在異常丟擲後的任何一個呼叫者處理該異常都可以。

異常處理如下:

def fn1():
    print('Hello fn')
    print(10 / 0)

def fn2():
    print('Hello fn2')
    fn1()

def fn3():
    print('Hello fn3')
    fn2()

try:
    fn3()
except :
    print("異常我已經處理過了。")
"""
輸出結果:
Hello fn3
Hello fn2
Hello fn
異常我已經處理過了。
"""
# 我在全域性作用域的地方進行了異常處理,
# 也可以在其他地方進行處理,不管在哪裡處理,
# 最後都不會把錯誤拋向控制檯的。

提示

當程式執行過程中出現異常以後,所有的異常資訊會被儲存一個專門的異常物件中。而異常傳播時,實際上就是將異常物件拋給了呼叫者。

而不同的錯誤,會對應著不同的異常物件(也就是前邊說的異常型別)。

如何檢視Python異常物件?

在Python的本地文件中,找到[The Python Standard Library] —> [Built-in Exceptions],裡面全是我們Python中的異常物件以及說明。

如下圖所示:

image

相關文章