1、異常的傳播
當在函式中出現異常時,如果在函式中對異常進行了處理,則異常不會再繼續傳播。如果函式中沒有對異常進行處理,則異常會繼續向函式呼叫者傳播。如果函式呼叫者處理了異常,則不再傳播,如果還沒有處理,則繼續向他的呼叫者傳播,直到傳遞到全域性作用域(主模組)如果依然沒有處理,則程式終止,並且顯示異常資訊到控制檯。所以異常的傳播我們也稱之為丟擲異常。
異常傳播示例如下:
def fn1():
print('Hello fn')
print(10/0)
def fn2():
print('Hello fn2')
fn()
def fn3():
print('Hello fn3')
fn2()
fn3()
輸出結果:
說明輸出結果:
當我們呼叫fn3()
方法的時候,會先輸出Hello fn3
,再向下執行呼叫fn2()
方法,以此類推到fn1()
方法中。可以看到上邊有三條輸出語句。
當執行到fn1()
方法中print(10/0)
語句,出現了ZeroDivisionError
異常,而fn1()
方法中沒有處理該異常,則向他的呼叫者丟擲這個異常,拋給了fn2()
方法,以此類推,知道fn3()
方法拋給了全域性作用域中的呼叫者,異常依然沒有被處理。
最後Python的直譯器會把這個異常顯示在控制檯中。
所以我們看到異常結果中,一行報錯,向上拋了好幾次。
例如:全域性作用域中的程式碼有異常沒有處理的話,就直接顯示在控制檯中了。
print(10 / 0)
輸出結果:
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中的異常物件以及說明。
如下圖所示: