1. 程式人生 > 程式設計 >通過例項瞭解Python異常處理機制底層實現

通過例項瞭解Python異常處理機制底層實現

要了解try except異常處理的用法,簡單來說,當位於 try 塊中的程式執行出現異常時,會將該種異常捕獲,同時找到對應的 except 塊處理該異常,那麼這裡就有一個問題,它是如何找到對應的 except 塊的呢?

我們知道,一個 try 塊也可以對應多個 except 塊,一個 except 塊可以同時處理多種異常。如果我們想使用一個 except 塊處理所有異常,就可以這樣寫:

try: #...except Exception: #...

這種情況下,對於 try 塊中可能出現的任何異常,Python直譯器都會交給僅有的這個 except 塊處理,因為它的引數是 Exception,表示可以接收任何型別的異常。

注意,對於可以接收任何異常的 except 來說,其後可以跟 Exception,也可以不跟任何引數,但表示的含義都是一樣的。

這裡就要詳細介紹一下 Exception。要知道,為了表示程式中可能出現的各種異常,Python 提供了大量的異常類,這些異常類之間有嚴格的繼承關係,圖 1 顯示了 Python 的常見異常類之間的繼承關係。

通過例項瞭解Python異常處理機制底層實現

從圖 1 中可以看出,BaseException 是Python 中所有異常類的基類,但對於我們來說,最主要的是Exception 類,因為程式中可能出現的各種異常,都繼承自 Exception。

因此,如果使用者要實現自定義異常,不應該繼承 BaseException ,而應該繼承 Exception 類。關於如何自定義一個異常類,可閱讀《Python自定義異常類》一節。

當 try 塊捕獲到異常物件後,Python 直譯器會拿這個異常型別依次和各個 except 塊指定的異常類進行比較,如果捕獲到的這個異常類,和某個 except 塊後的異常類一樣,又或者是該異常類的子類,那麼 Python 直譯器就會呼叫這個 except 塊來處理異常;反之,Python 直譯器會繼續比較,直到和最後一個 except 比較完,如果沒有比對成功,則證明該異常無法處理。

圖 2 演示了位於 try 塊中的程式發生異常時,從捕獲異常到處理異常的整個流程。

通過例項瞭解Python異常處理機制底層實現

下面看幾個簡單的異常捕獲的例子:

try:
  a = int(input("輸入 a:"))
  b = int(input("輸入 b:"))
  print( a/b )
except ValueError:
  print("數值錯誤:程式只能接收整數引數")
except ArithmeticError:
  print("算術錯誤")
except Exception:
  print("未知異常")

該程式中,根據使用者輸入 a 和 b 值的不同,可能會導致 ValueError、ArithmeticError 異常:

  • 如果使用者輸入的 a 或者 b 是其他字元,而不是數字,會發生 ValueError 異常,try 塊會捕獲到該型別異常,同時 Python 直譯器會呼叫第一個 except 塊處理異常;
  • 如果使用者輸入的 a 和 b 是數字,但 b 的值為 0,由於在進行除法運算時除數不能為 0,因此會發生 ArithmeticError 異常,try 塊會捕獲該異常,同時 Python 直譯器會呼叫第二個 except 塊處理異常;
  • 當然,程式執行過程中,還可能由於其他因素出現異常,try 塊都可以捕獲,同時 Python 會呼叫最後一個 except 塊來處理。

當一個 try 塊配有多個 except 塊時,這些 except 塊應遵循這樣一個排序規則,即可處理全部異常的 except 塊(引數為 Exception,也可以什麼都不寫)要放到所有 except 塊的後面,且所有父類異常的 except 塊要放到子類異常的 except 塊的後面。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。