一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Python - Python中優雅使用assert斷言的方法實例

Python中優雅使用assert斷言的方法實例

2022-01-07 10:47王坤祥 Python

我們在開發一個程序時候,與其讓它運行時崩潰,不如在它出現錯誤條件時就崩潰(返回錯誤),這時候斷言assert就顯得非常有用,這篇文章主要給大家介紹了關于Python中優雅使用assert斷言的相關資料,需要的朋友可以參考下

什么是 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 等價于

?
1
2
if __debug__:
    if not expression: raise AssertionError

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

?
1
2
if __debug__:
    if not expression1: raise AssertionError(expression2)

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

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

?
1
2
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 方法。

?
1
2
3
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 所指定的文件需要是存在的,并且當前用戶有權限讀取該文件,這些條件稱為后驗條件,對于后驗條件的檢查,我們需要使用異常來處理。

?
1
2
3
4
5
6
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,使用異常可以拋出更詳細的錯誤,方便上層代碼針對不同錯誤執行不同的邏輯。

使用斷言的幾個原則

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

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

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

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

?
1
2
3
4
5
#當我們執行到這里,我們知道n>2
 
#你可以確保在運行時用以下斷言:
 
assert n > 2

建議不使用斷言的情況:

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

總結

到此這篇關于Python中優雅使用assert斷言的文章就介紹到這了,更多相關Python優雅使用assert斷言內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://xie.infoq.cn/article/62388d990f852ad93863f35e5

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 美女被灌浣肠失禁视频 | 嫩草视频在线观看视频播放 | 日本成熟bbxxxxxxxx | 四虎影视4hu最新地址在线884 | 国产在线观看色 | 五月天黄网 | 亚洲男人的天堂网站 | 日本免费久久久久久久网站 | 韩日视频在线观看 | 俄罗斯bbbbbbxxxxxx| 半挠脚心半黄的网站 | 动漫人物差差差动漫人物免费观看 | 放荡护士玩3p口述 | 美日毛片| 男人j放进女人的p免费看视频 | 奇米影视奇米色777欧美 | 被黑人同学彻底征服全文小说阅读 | 午夜精品网站 | 性绞姿始动作动态图 | 日本午夜小视频 | 日韩一区二区三区精品 | 高清国产精品久久久久 | 日本老师xxxxx18 | 天天综合色天天综合 | 亚洲天堂成人在线观看 | 男人操美女视频 | 欧美视频一区二区三区在线观看 | 成人蜜桃网| 日韩无砖专区体验区 | 韩日视频在线 | 亚洲久草 | 久久婷婷五月综合色丁香花 | 国内精品视频一区二区三区八戒 | 6080窝窝理论| 青青草高清视频 | 日本免费一区二区三区a区 日本免费三片在线观看 | 日韩欧美高清一区 | 2023毛片| 白丝校花掀起短裙呻吟小说 | 亚洲AV无码专区国产乱码网站 | 暴露狂婷婷医院暴露tx |