2012-03-29 23 views
2

我對程序狀態進行了許多檢查,其失敗將指示代碼中的錯誤。在這種情況下,我喜歡使用assert condition,因爲它比if not condition: raise MyException更好。使用assert代替raise有兩個問題。儘管存在-O(優化)標誌,仍然保持斷言

  1. assert不允許指定要引發的異常,所以抓住它後來變成硬(捕AssertionError可能趕上太多)。

  2. 當-O標誌被傳遞給解釋器時,assert被禁用。

在我的環境代碼中的任何錯誤需要我放棄任何結果,直到錯誤被發現和解決。因此,上述檢查引發的例外沒有意義。因此,問題#1與我的情況無關。

問題2嚴重。我希望我的支票保留在生產代碼中,因爲正確性比我的環境中的性能重要得多。很少有人今天使用-O標誌;但有一天我或其他人可能更願意使用它(例如,爲了抑制if __debug__後面的代碼,或者因爲-O將來可能會實際優化代碼)。由於我的所有assert語句都必須在生產代碼中保持活動狀態,因此我需要用其他名稱替換所有assert語句。有沒有辦法強制assert留下儘管-O標誌?

順便說一句,我打算通過打印導致斷言失敗的行中的變量值來定製assert的行爲。我想我可以用sys.excepthook替換sys.excepthook,這個函數可以捕獲AssertionError,讀取回溯,找到相關的源代碼,打印相關行中的變量,然後重新評估異常。如果有人發現有問題,請告訴我。

+0

我假設你正在使用'assert'識別災難性故障條件,而不僅僅是普通的異常情況? – 2012-03-29 16:27:08

+0

準確。我仍然使用適當的異常來捕捉異常輸入等 - 我只使用'assert'來捕獲代碼中的錯誤。在我的特定環境中,代碼中的任何錯誤都被認爲是災難性的失敗(如果生產代碼包含任何已知的錯誤,則不允許運行)。 – max 2012-03-29 16:30:41

+0

它看起來不太好。刪除斷言顯然是-O開關的一個「特徵」。 http://stackoverflow.com/q/1273211/102937 – 2012-03-29 16:44:21

回答

3

只是不使用斷言,如果他們不是你所需要的。相反,要明確的是,如果違反了某些條件,您將拋出此異常。斷言聲明總是帶有「我可能不會被運行」的一面。它不那麼黑客,不那麼令人驚訝,未來不太可能破解,也不需要您阻止用戶添加-O

如果你只是想保存輸入,你可以這樣做。創建這樣的功能(強烈建議更具體的名稱),並使用它,而不是assert

def require(cond, msg): 
    if not cond: 
     raise MyException(msg) 
相關問題