什么是assert斷言
Assert statements are a convenient way to insert debugging assertions into a program
斷言聲明是用于程序調(diào)試的一個便捷方式腕侄。斷言可以看做是一個debug工具淮阐,Python的實現(xiàn)也符合這個設計哲學甩卓,在Python中assert語句的執(zhí)行是依賴于__debug__
這個內(nèi)置變量的祭衩,其默認值為True
韭赘。當__debug__
為True
時赂韵,assert語句才會被執(zhí)行蝴悉。
對于一般的聲明辫红,assert expression等價于
if __debug__:
if not expression: raise AssertionError
assert可以同時聲明兩個個expression晴裹,例如assert expression1, expression2等價于
if __debug__:
if not expression1: raise AssertionError(expression2)
如果執(zhí)行腳本文件時加上-O
參數(shù)被济, __debug__
則為False
舉一個例子,假設我們有一個腳本testAssert.py涧团,內(nèi)容為:
print(__debug__)
assert 1 > 2
當使用python assert.py
運行時只磷,__debug__
會輸出True,assert 1 > 2語句會拋出AssertionError異常泌绣。
當使用python -O assert.py
運行時钮追,__debug__
會輸出False,assert 1 > 2語句由于沒有執(zhí)行不會報任何異常阿迈。
斷言和異常的使用場景
先說結(jié)論:
檢查先驗條件使用斷言元媚,檢查后驗條件使用異常
舉個例子來說明一下,在開發(fā)中我們經(jīng)常會遇到讀取本地文件的場景苗沧。我們定義一個read_file方法刊棕。
def read_file(path):
assert isinstance(file_path, str)
...
read_file函數(shù)要求在開始執(zhí)行的時候滿足一定條件:file_path必須是str類型,這個條件就是先驗條件待逞,如果不滿足鞠绰,就不能調(diào)用這個函數(shù),如果真的出現(xiàn)了不滿足條件的情況飒焦,證明代碼中出現(xiàn)了bug蜈膨,這時候我們就可以使用assert語句來對file_path的類型進行推斷屿笼,提醒程序員修改代碼,也可以使用if...raise...語句來實現(xiàn)assert翁巍,但是要繁瑣很多驴一。在很多優(yōu)秀的Python項目中都會看到使用assert進行先驗判斷的情況,平時可以多多留意灶壶。
read_file函數(shù)在被調(diào)用執(zhí)行后肝断,依然需要滿足一定條件,比如file_path所指定的文件需要是存在的驰凛,并且當前用戶有權(quán)限讀取該文件胸懈,這些條件稱為后驗條件,對于后驗條件的檢查恰响,我們需要使用異常來處理趣钱。
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()
文件不存在和沒有權(quán)限,這兩種情況并不屬于代碼bug胚宦,是代碼邏輯的一部分首有,上層代碼捕獲異常后可能會執(zhí)行其他邏輯,因此我們不能接受這部分代碼在生產(chǎn)環(huán)境中被忽略枢劝。并且井联,相比于assert語句只能拋出AssertionError,使用異衬裕可以拋出更詳細的錯誤烙常,方便上層代碼針對不同錯誤執(zhí)行不同的邏輯。