91個建議系列之4 利用assert語句來發現問題

2021-10-23 05:35:05 字數 2041 閱讀 2640

斷言(assert)在很多語言中都存在,它主要為除錯程式服務,能夠快速方便地檢查程式的異常或者發現不恰當的輸入等,可防止意想不到的情況出現。以前你經常使用斷點+print進行除錯,但現在你有更簡潔的語法來實現它:

# 斷言更簡潔:

assert x == y,

"not equals"

# 傳統除錯print:

if x == y:

print

("not equal"

)

assert的基本語法就:

assert  expression1 [

"," expression2]

如果表示式expression1的結果為true,則繼續往下進行,如果為false會引發assertionerror,而expression 2是可選的,常用來傳遞具體的異常資訊。assert在執行上等價於採用raise丟擲異常:

if __debug__ and

not x == y:

raise assertionerror(

"not equals"

)

使用斷言要注意以下問題:

斷言是有代價的,它會對效能產生一定的影響,對於編譯型的語言,如c/c++,這也許並不那麼重要,因為斷言只在除錯模式下啟用。但python並沒有嚴格定義除錯和發布模式之間的區別,通常禁用斷言的方法是在執行指令碼的時候加上-o標誌,這種方式帶來的影響是它並不優化位元組碼,而是忽略與斷言相關的語句。如:

python asserttest.py # 斷言模式

python -o asserttest.py # 禁用斷言

斷言實際是被設計用來捕獲使用者所定義的約束的,而不是用來捕獲程式本身錯誤的,因此使用斷言需要注意以下幾點:

1)不要濫用,這是使用斷言最基本的原則。若由於斷言引發了異常,通常代表程式中存在bug。因此斷言應該使用在正常邏輯不可到達的地方或正常情況下總是為真的場合。

2)如果python本身的異常能夠處理就不要再使用斷言。如對於類似於陣列越界、型別不匹配、除數為0之類的錯誤,不建議使用斷言來進行處理。比如下面的例子,如果除數為0,本身python就會丟擲zerodivisionerror,使用assert毫無意義。

def

mydivide

(x,y)

:"返回x/y的值"

# assert y!=0,'divider cannot be 0'

return x/y

mydivide(1,

0)

又或者型別不匹配

def

myfun

(s:str):

# assert isinstance(s,str),"para should be str"

return s.upper(

)myfun([1

,2,3

])

如果輸入不是列表,不用你斷言系統就會丟擲attributeerror。

3)不要使用斷言來檢查使用者的輸入。如對於乙個數字型別,如果根據使用者的設計該值的範圍應該是2~10,較好的做法是使用條件判斷,並在不符合條件的時候輸出錯誤提示資訊,不要寫成

assert

2"range error"

4)在函式呼叫後,當需要確認返回值是否合理時可以使用斷言。

5)當條件是業務邏輯繼續下去的先決條件時可以使用斷言。如list1和其副本list2,業務繼續下去的條件是這兩個list必須是一樣的,但由於某些不可控因素,如使用了淺拷貝而list1中含有可變物件等,就可以使用斷言來判斷這兩者的關係,如果不相等,則繼續執行後面的程式意義不大。

6)斷言用於非常特別的失敗條件,如果這個錯誤經常出現,你就應該調整過**,而不是用assert。你的使用者絕不看到乙個assertionerror,如果看到了,那就是個必須修復的缺陷

綜上所述,assert適用於特別情況下的**邏輯錯誤,其餘情況下應該慎重使用,否則容易畫蛇添足哦。

摘選改善Python程式的91個建議2

62 metaclass stackflow 中文翻譯 63 python物件協議 65 python的迭代器協議 iter 可迭代物件 返回迭代器iterator 呼叫 呼叫一次返回乙個元素,當最後乙個元素返回後,再次呼叫時,丟擲stopiteration 異常 iterator.next 或 n...

改善python程式的91個建議讀書筆記1

引論 建議1 理解pythonic 的概念pythonic 也許可以遮陽定義 充分體現python 自身特色的 風格。python 中兩個變數交換只需一行 a,b b,a 遍歷乙個容器時可以為 for i in alist do sth with i 開啟檔案,需要安全的關閉檔案可以為 with o...

改善python程式的91個建議讀書筆記 3

建議7.將常量集中到乙個檔案 python的內建命名空間是支援一小部分常量的,如true,false,none.只是python沒有提供定義常量的直接方式而已.那麼在python中應該如何使用常量呢?一般來說有以下兩種方法 1.通過命名風格來提醒使用者該變數代表的意義為常量.如常量名所有字母大寫,用...