Python中如何優雅的使用assert斷言


https://zhuanlan.zhihu.com/p/91853234

什么是assert斷言

Assert statements are a convenient way to insert debugging assertions into a program

斷言聲明是用於程序調試的一個便捷方式。斷言可以看做是一個debug工具,Python的實現也符合這個設計哲學,在Python中assert語句的執行是依賴於__debug__這個內置變量的,其默認值為True。當__debug__為True時,assert語句才會被執行。

對於一般的聲明,assert expression等價於

if __debug__:
    if not expression: raise AssertionError

assert可以同時聲明兩個expression,例如assert expression1, expression2等價於

if __debug__:
    if not expression1: raise AssertionError(expression2)

如果執行腳本文件時加上-O參數, __debug__則為False

舉一個例子,假設我們有一個腳本testAssert.py,內容為:

print(__debug__)
assert 1 > 2

當使用python assert.py運行時,__debug__會輸出True,assert 1 > 2語句會拋出AssertionError異常。

當使用python -O assert.py運行時,__debug__會輸出False,assert 1 > 2語句由於沒有執行不會報任何異常。

斷言和異常的使用場景

先說結論:

檢查先驗條件使用斷言,檢查后驗條件使用異常

舉個例子來說明一下,在開發中我們經常會遇到讀取本地文件的場景。我們定義一個read_file方法。

def read_file(path):
    assert isinstance(file_path, str)
    ...

read_file函數要求在開始執行的時候滿足一定條件:file_path必須是str類型,這個條件就是先驗條件,如果不滿足,就不能調用這個函數,如果真的出現了不滿足條件的情況,證明代碼中出現了bug,這時候我們就可以使用assert語句來對file_path的類型進行推斷,提醒程序員修改代碼,也可以使用if...raise...語句來實現assert,但是要繁瑣很多。在很多優秀的Python項目中都會看到使用assert進行先驗判斷的情況,平時可以多多留意。

read_file函數在被調用執行后,依然需要滿足一定條件,比如file_path所指定的文件需要是存在的,並且當前用戶有權限讀取該文件,這些條件稱為后驗條件,對於后驗條件的檢查,我們需要使用異常來處理。

def read_file(file_path):
    assert isinstance(file_path, str)
    if not check_exist(file_path):
        raise FileNotFoundError()
    if not has_privilege(file_path):
        raise PermissionError()

文件不存在和沒有權限,這兩種情況並不屬於代碼bug,是代碼邏輯的一部分,上層代碼捕獲異常后可能會執行其他邏輯,因此我們不能接受這部分代碼在生產環境中被忽略,這屬於后驗條件。並且,相比於assert語句只能拋出AssertionError,使用異常可以拋出更詳細的錯誤,方便上層代碼針對不同錯誤執行不同的邏輯。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM