Python編程思想(33):異常類與多異常捕獲

李寧老師已經在「極客起源」 微信公衆號推出《Python編程思想》電子書,囊括了Python的核心技術,以及Python的主要函數庫的使用方法。讀者可以在「極客起源」 公衆號中輸入 160442 開始學習。

 

《Python編程思想》總目錄
《Python編程思想》專欄

1. 異常類

當 Python解釋器接收到異常對象時,如何爲該異常對象尋找 except塊呢?注意到前面的代碼中的except塊,這個塊是專門用於處理該異常類及其子類的異常實例。

當 Python解釋器接收到異常對象後,會依次判斷該異常對象是否是 except塊後的異常類或其子類的實例,如果是, Python解釋器將調用該 except塊來處理該異常;否則,再次拿該異常對象和下一個 except塊裏的異常類進行比較。 Python異常捕獲的流程如下:

try
    statement1
    statement2  # 拋出異常,產生一個Error對象,需要Exception2進行處理
    ... ...
    # 後面的語句將不再執行      
except Exception1:  # Error會與Exception1比較
    # 處理Exception1
    # 不再執行其他處理異常的塊 
    ...
except Exception2:  # Error會與Exception2比較,該塊可以處理statement2拋出的Error對象
    # 處理Exception2
    # 不再執行其他處理異常的塊 
    ...

從上面的流程可以看出,在try塊後可以有多個 except塊,這是爲了針對不同的異常類提供不同的異常處理方式。當程序發生不同的意外情況時,系統會生成不同的異常對象, Python解釋器就會根據該異常對象所屬的異常類來決定使用哪個 except塊來處理該異常。

通過在try塊後提供多個 except塊可以無須在異常處理塊中使用if判斷異常類型,但依然可以針對不同的異常類型提供相應的處理邏輯,從而提供更細緻、更有條理的異常處理邏輯。

在通常情況下,如果try塊被執行一次,則try塊後只有一個 except塊會被執行,不可能有多個 except塊被執行。除非在循環中使用了 continue開始下一次循環,下次循環又重新運行了try塊,這纔可能導致多個 except塊被執行。

Python的所有異常類都從 BaseException類派生而來,提供了豐富的異常類,這些異常類之間有嚴格的繼承關係,下圖顯示了 Python的常見異常類之間的繼承關係。

從這張圖中可以看出, Python的所有異常類的基類是 Base Exception,但如果用戶要實現自定義異常,則不應該繼承這個基類,而應該從 Exception類繼承。

BaseException的主要子類就是 Exception,不管是系統的異常類,還是用戶自定義的異常類,都應該從 Exception類派生。下面看一個簡單的異常捕獲的例子:
示例代碼:div_demo. py

import sys
try:
    a = int(sys.argv[1])
    b = int(sys.argv[2])
    c = a / b
    print("您輸入的兩個數相除的結果是:", c )
except IndexError:
    print("索引錯誤:運行程序時輸入的參數個數不夠")
except ValueError:
    print("數值錯誤:程序只能接收整數參數")
except ArithmeticError:
    print("算術錯誤")
except Exception:
    print("未知異常")

這段代碼導入了sys模塊,並通過sys模塊的argv列表來獲取運行 Python程序時提供的參數(命令行參數)。其中 sys.argv[0]通常代表正在運行的 Python程序名,sys. argv[1]代表運行程序所提供的第1個參數,sys.argv[2]代表運行程序所提供的第2個參數……依此類推。

這段代碼針對 IndexError、 ValueError、 ArithmeticError類型的異常,提供了專門的異常處理邏輯。該程序運行時的異常處理邏輯可能有如下幾種情形:

  • 如果在運行該程序時輸入的參數不夠,將會發生索引錯誤,Python將調用 IndexError對應的 except塊處理該異常;
  • 如果在運行該程序時輸入的參數不是數字,而是字母,將發生數值錯誤, Python將調用ValueError對應的 except塊處理該異常;
  • 如果在運行該程序時輸入的第2個參數是0,將發生除0異常, Python將調用 ArithmeticError對應的 except塊處理該異常;
  • 如果在程序運行時出現其他異常,該異常對象總是 Exception類或其子類的實例,Python將調用 Exception對應的 except塊處理該異常。

上面程序中的3種異常,都是非常常見的運行時異常,讀者應該記住這些異常,並掌握在哪些情況下可能出現這些異常。

2. 多異常捕獲

Python的一個 except塊可以捕獲多種類型的異常。在使用一個 except塊捕獲多種類型的異常時,只要將多個異常類用圓括號括起來,中間用逗號隔開即可。
下面演示了 Python的多異常捕獲:
示例代碼:multi_exception_demo.py

import sys
try:
    a = int(sys.argv[1])
    b = int(sys.argv[2])
    c = a / b
    print("您輸入的兩個數相除的結果是:", c )
except (IndexError, ValueError, ArithmeticError):
    print("程序發生了數組越界、數字格式異常、算術異常之一")
except:
    print("未知異常")

在這段程序中使用了 (IndexError, ValueError, ArithmeticError)來指定所捕獲的異常類型,這就表明該 except塊可以同時捕獲這3種類型的異常。

----------------支持作者請轉發本文,也可以加李寧老師微信:unitymarvel,或掃描下面二維碼加微信--------


在這裏插入圖片描述

歡迎關注 極客起源 微信公衆號,更多精彩視頻和文章等着你哦!
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章