除錯斷言失敗 一日一技 python中的斷言

2021-10-12 09:45:26 字數 2739 閱讀 9113

一、使用python中的斷言來自動檢測python程式中的錯誤,讓程式更加可靠且更易於除錯

從根本上來說,python中的斷言語句是一種除錯工具,用來測試某個斷言條件,如果斷言條件為true,則程式將繼續正常執行;但如果斷言條件為假false,則會引發assertionerror異常並顯示相關的錯誤訊息。

示例: price = int(product['price'] * (1 - discount))

assert 0 <= price <= product['price'] # 斷言

return price

注意到assert語句了嗎?這條語句確保在任何情況下,通過該函式計算的折後**不低於0,也不會高於產品原價。

下面建立乙個示例產品,一雙**為1000元的鞋子,現在如果為這雙鞋打五折,則**應該變為500,對該函式進行測試:

還不錯,接著我們再嘗試使用一些無效的折扣,比如200%的」折扣「會讓商家向顧客付錢:

二、為什麼不用普通的異常來處理?

斷言是為了告訴開發人員程式中發生了不可恢復的錯誤,對於可以預料的錯誤(如未找到相關檔案),使用者可以予以糾正或重試,斷言並不是為此而生的。

如果程式沒有bug,那麼這些斷言條件永遠也不會觸發,但如果違反了斷言條件,程式就會崩潰並報告斷言錯誤,告訴開發人員究竟違反了哪個「不可能」的情況,這樣可以更輕鬆的追蹤和修復程式中的bug。python中的斷言語句是一種除錯輔助功能,不是用來處理執行時錯誤的機制,使用斷言的目的是讓開發人員更快速的找到可能導致bug的根本原因,除非程式中存在bug,否則絕不會丟擲斷言錯誤。

三、assert語法及使用注意事項

語法:

assert 《斷言判斷條件》 [,"錯誤提示訊息"]
其中的錯誤提示訊息是可選的,如果加了錯誤提示訊息,則會在丟擲異常時,同異常訊息一同展示,如:

注意事項:

在python中使用斷言時,需要注意,第一:斷言會給應用程式帶來安全風險和bug;第二:容易寫出很多無用的斷言語句。

1、不用使用斷言驗證資料

在python中使用斷言時要注意的乙個重點是,若在命令列中使用-o和-oo標識,或修改cpython中的pythonoptimize環境變數,都會全域性禁用斷言。此時所有的斷言語句都會無效,程式會直接略過而不處理斷言,因此不會執行任何條件表示式,因此使用斷言語句來快速驗證輸入資料非常危險。

def delete_product(prod_id, user):

assert user.is_admin(), "must be admin."

assert store.has_product(prod_id), "unknown product."

store.get_product(prod_id).delete()

仔細看這個函式,如果斷言被禁用後會發生什麼?這個僅有三行**的函式示例存在兩個嚴重的問題:

(2)禁用斷言後會跳過has_product()檢查,這意味著可以使用無效的產品id呼叫get_product(),這可能會導致更嚴重的bug,具體情況取決於程式的編寫方式,在最糟糕的情況下,有人可以藉此對**發起拒絕服務攻擊。例如:如果嘗試刪除未知產品會導致**應用程式崩潰,那麼 攻擊者就可以傳送大量無效的刪除請求讓程式無法正常工作。

那麼如何避免這些問題呢?答案是絕對不要使用斷言來驗證資料,而是使用常規的 if 語句驗證,並在必要的時候觸發驗證異常,如下所示:

def delete_product(prod_id, user):

if not user.is_admin():

raise autherror("must be admin.")

if not store.has_product(prod_id):

raise valueerror("unknown product.")

store.get_product(prod_id).delete()

修改後的示例還有個好處,即**不會觸發通用的assertionerror異常,而是觸發與語義相關的異常,如valueerror或autherror。

2、永不失敗的斷言

開發人員很容易就會新增許多總是為true的python斷言,因此這些語句毫無用處,永遠不會觸發異常。

四、總結

儘管有這些需要注意的事項,但python的斷言依然是功能強大的除錯工具,了解斷言的工作方式及其使用場景有助於編寫更易於維護和除錯的python程式,學習斷言有助於將個人的python知識提公升到新的水平。

關鍵要點:

一日一結2012 5 2

今天去圖書館把作業系統概念借到了,期待很久,欣喜萬分。專業知識部分 今天主要學習了一下mfc六大關鍵技術,感覺講得不錯。主要的例子是以基於文件類的程式,感覺學到了東西。以前看孫新老師的書時是有點半知不解,看了這個資料讓我對mfc程式的內部有了更深一層的理解。課外知識部分 看完10000小時code ...

一日一結2012 5 6

今天天氣很熱,感覺已經進入夏天。看了galaxy 3 效能評測,不錯。專業知識部分 今天看了作業系統概念的虛擬記憶體,了解了虛擬記憶體的概念和原理,虛擬記憶體這種記憶體管理技術允許執行程序不必完全在記憶體中。而且,虛擬記憶體將記憶體抽象成乙個巨大的 統一的儲存陣列,進而將使用者看到的邏輯記憶體和物理...

一日小結(04 19)

聽了老賀的建議,來到csdn上來寫部落格 今天stm32是一點都沒有學,原本計畫著晚上7點開始學的,沒成想3d印表機出問題了 沒料打了乙個半成品 配合月哥搗鼓了半天才把黑色的料換好,不過雖然stm32上沒有比昨天更進一步,但還是學到了挺多東西的 今天學習了指標中的void指標和null指標 void...