人妖在线一区,国产日韩欧美一区二区综合在线,国产啪精品视频网站免费,欧美内射深插日本少妇

新聞動態(tài)

Python中優(yōu)雅使用assert斷言的方法實例

發(fā)布日期:2022-01-03 00:58 | 文章來源:gibhub

什么是 assert 斷言

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

斷言聲明是用于程序調(diào)試的一個便捷方式。斷言可以看做是一個 debug 工具,Python 的實現(xiàn)也符合這個設(shè)計哲學(xué),在 Python 中 assert 語句的執(zhí)行是依賴于__debug__這個內(nèi)置變量的,其默認值為True。當(dāng)__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

舉一個例子,假設(shè)我們有一個腳本 testAssert.py,內(nèi)容為:

print(__debug__)
assert 1 > 2

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

當(dāng)使用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 所指定的文件需要是存在的,并且當(dāng)前用戶有權(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,使用異??梢話伋龈敿毜腻e誤,方便上層代碼針對不同錯誤執(zhí)行不同的邏輯。

使用斷言的幾個原則

  1. 使用斷言捕捉不應(yīng)該發(fā)生的非法情況。不要混淆非法情況與錯誤情況之間的區(qū)別,后者是必然存在的并且是一定要作出處理的。
  2. 使用斷言對函數(shù)的參數(shù)進行確認。
  3. 在編寫函數(shù)時,要進行反復(fù)的考查,并且自問:“我打算做哪些假定?”一旦確定了的假定,就要使用斷言對假定進行檢查。
  4. 一般教科書都鼓勵程序員們進行防錯性的程序設(shè)計,但要記住這種編程風(fēng)格會隱瞞錯誤。當(dāng)進行防錯性編程時,如果“不可能發(fā)生”的事情的確發(fā)生了,則要使用斷言進行報警。

斷言也可以用于代碼測試,用作一個做事毛手毛腳的開發(fā)人員的單元測試,只要能你接受當(dāng)使用-O標(biāo)志時這個測試什么都不做。我有時也會在代碼中用"assert Fasle"來對還沒有實現(xiàn)的分支作標(biāo)記,當(dāng)然我希望他們失敗。如果稍微更細節(jié)一些,或許觸發(fā)NotImplementedError是更好的選擇

另一個斷言用得好的地方就是檢查程序中的不變量。一個不變量是一些你能相信為真的條件,除非一個缺陷導(dǎo)致它變成假。如果有一個缺陷,越早發(fā)現(xiàn)越好,因此我們需要對其進行測試,但我們不想因為這些測試而影響代碼執(zhí)行速度。因此采用斷言,它能在開發(fā)時生效而在產(chǎn)品中失效。

斷言也是一個很好的檢查點注釋。為了替代如下注釋:

#當(dāng)我們執(zhí)行到這里,我們知道n>2 
 
#你可以確保在運行時用以下斷言:
 
assert n > 2

建議不使用斷言的情況:

  • 不要用于測試用戶提供的數(shù)據(jù),或者那些需要在所有情況下需要改變檢查的地方
  • 不要用于檢查你認為在通常使用中可能失敗的地方。斷言用于非常特別的失敗條件。你的用戶絕不看到一個AssertionError,如果看到了,那就是個必須修復(fù)的缺陷。
  • 特別地不要因為斷言只是比一個明確的測試加一個觸發(fā)異常矮小而使用它。斷言不是懶惰的代碼編寫者的捷徑。
  • 不要將斷言用于公共函數(shù)庫輸入?yún)?shù)的檢查,因為你不能控制調(diào)用者,并且不能保證它不破壞函數(shù)的合約。
  • 不要將斷言用于你期望修改的任何錯誤。換句話,你沒有任何理由在產(chǎn)品代碼捕獲一個AssertionError異常。
  • 不要太多使用斷言,它們使代碼變得晦澀難懂。

總結(jié)

到此這篇關(guān)于Python中優(yōu)雅使用assert斷言的文章就介紹到這了,更多相關(guān)Python優(yōu)雅使用assert斷言內(nèi)容請搜索本站以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持本站!

版權(quán)聲明:本站文章來源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請保持原文完整并注明來源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學(xué)習(xí)參考,不代表本站立場,如有內(nèi)容涉嫌侵權(quán),請聯(lián)系alex-e#qq.com處理。

相關(guān)文章

實時開通

自選配置、實時開通

免備案

全球線路精選!

全天候客戶服務(wù)

7x24全年不間斷在線

專屬顧問服務(wù)

1對1客戶咨詢顧問

在線
客服

在線客服:7*24小時在線

客服
熱線

400-630-3752
7*24小時客服服務(wù)熱線

關(guān)注
微信

關(guān)注官方微信
頂部