python之warnings模組(warnings.filterwarnings("ignore")程式碼解析)
前言
①Python通過呼叫warnings 模組中定義的warn() 函式來發出警告。
②警告訊息通常用於提示使用者一些錯誤或者過時的用法,當這些情況發生時我們不希望丟擲異常或者直接退出程式。
③警告訊息通常寫入sys.stderr,對警告的處理方式可以靈活的更改,例如忽略或者轉變為為異常。警告的處理可以根據警告類別,警告訊息的文字和發出警告訊息的源位置而變化。對相同源位置的特定警告的重複通常被抑制。
④警告控制分為兩個階段:首先,警告被觸發時,確定是否應該發出訊息(警告過濾器);接下來,如果要發出訊息,則使用使用者可設定的鉤子來格式化和列印訊息。
⑤警告過濾器可以用來控制是否發出警告訊息,警告過濾器是一些匹配規則和動作的序列。可以通過呼叫filterwarnings()
⑥警告訊息的輸出是通過呼叫showwarning() 函式來完成的,其可以被覆蓋;該函式的預設實現通過呼叫formatwarning() 格式化訊息,這也可以由自定義實現使用。
警告類別
內建警告型別:
可以通過繼承內建警告型別來實現自定義的警告型別,警告型別必須始終是Warning
類的子類。
警告過濾器
警告過濾器用於控制警告的行為,如忽略,顯示或轉換為錯誤(引發異常)。
警告過濾器維護著一個有序的過濾規則列表,匹配規則用於確定如何處理警告,任何特定警告都將依次與列表中的每個過濾規則匹配,直到找到匹配為止。過濾規則型別為一個元組 (action,message,category,module,lineno);
其中:
- action為以下值:
- message是包含正則表示式的字串,警告訊息的開始必須匹配,不區分大小寫
- category是一個警告型別(必須是 Warning 的子類)
- module是包含模組名稱的正則表示式字串,區分大小寫
- lineno是一個整數,警告發生的行號,為 0 則匹配所有行號
預設警告過濾器
預設情況下,Python 設定了幾個警告過濾器,可以通過 -W 命令列選項和呼叫 filterwarnings()函式來覆蓋它們。
- DeprecationWarning和PendingDeprecationWarning 和ImportWarning 被預設忽略。
- 除非-b選項給出一次或兩次,否則忽略 BytesWarning
- 除非 Python 是在除錯模式下構建的,否則將忽略 ResourceWarning。
在 3.2 版中的調整: 除PendingDeprecationWarning 之外,預設情況下將忽略DeprecationWarning
可用函式
①warn
warnings.warn(message, category=None, stacklevel=1, source=None)
觸發異常。category引數預設為 UserWarning。message引數為警告訊息,可以是 Warning 例項,在這種情況下,將忽略category 並使用message.__class__,訊息文字則為 str(message)。
這是 warn()函式的低階介面,明確傳遞訊息,類別,檔名和行號,以及可選的模組名稱和登錄檔(應該是模組的__warningregistry__ 字典)
②showwarning
warnings.showwarning(message, category, filename, lineno, file=None, line=None)
寫入警告到檔案。預設呼叫formatwarning(message, category, filename, lineno, line) 並將結果字串寫入 file,預設為 sys.stderr。 line 是包含在警告訊息中的一行原始碼;如果未提供則嘗試讀取由 filename 和 lineno 指定的行。
③formatwarning
warnings.formatwarning(message, category, filename, lineno, line=None)
格式化警告,返回一個字串。可能包含嵌入的換行符,並以換行符結束。line
是包含在警告訊息中的一行原始碼;如果不提供則嘗試讀取由 filename 和 lineno 指定的行。
④filterwarnings
warnings.filterwarnings(action, message='', category=Warning, module='', lineno=0, append=False)
過濾警告,在 警告過濾器規則 列表中插入一個條目。預設情況下,條目插入在前面;如果 append 為真,則在末尾插入。它檢查引數的型別,編譯 message 和 module 的正則表示式,並將它們作為警告過濾器列表中的元組插入。如果多個地方都匹配特定的警告,那麼更靠近列表前面的條目會覆蓋列表中後面的條目,省略的引數預設為匹配一切的值。
⑤simplefilter
warnings.simplefilter(action, category=Warning, lineno=0, append=False)
簡單易用的過濾器,類似filterwarnings()函式,但是不需要正則表示式。
⑥resetwarnings
warnings.resetwarnings()
重置警告過濾器。這會丟棄所有以前對filterwarnings()呼叫的影響,包括 -W 命令列選項和對simplefilter()的呼叫的影響。
可用的上下文管理器
class warnings.catch_warnings(*, record=False, module=None)
捕獲警告,在退出上下文時恢復警告過濾器和 showwarning() 函式功能。如果 record 引數是 False (預設值),則上下文管理器在入口處返回 None。如果 record 是 True,則返回一個列表,該列表元素為 showwarning() 函式所見的物件,列表中的每個元素都具有與 showwarning() 的引數具有相同名稱的屬性。
import warnings warnings.simplefilter("always") def fxn(): warnings.warn("this is a warning", Warning) with warnings.catch_warnings(): warnings.simplefilter("ignore") fxn() with warnings.catch_warnings(Warning): warnings.warn("this is a warning2", Warning) warnings.warn("this is a warning3", Warning) def fxn2(): warnings.warn("deprecated", DeprecationWarning) with warnings.catch_warnings(record=True) as w: # Cause all warnings to always be triggered. warnings.simplefilter("always") # Trigger a warning. fxn2() # Verify some things assert len(w) == 1 assert issubclass(w[-1].category, DeprecationWarning) assert "deprecated" in str(w[-1].message)
可以從命令列通過傳遞 -Wd 引數到直譯器(即為 -W default 的速記)。這將為所有警告啟用預設處理,包括預設情況下忽略的警告。要更改遇到的警告所採取的操作,只需更改傳遞給 -W 的引數即可,如 -W error。可以用 python --help 來檢視 -W 引數的詳細使用。
在程式碼中實現 -Wd 的功能為:
warnings.simplefilter('default')
這樣的程式碼應該在程式開始被執行,否則有些警告可能仍然會被觸發。
通過警告過濾器進行控制忽略發出警告訊息:
程式碼如下:
import warnings warnings.filterwarnings('ignore')
命令列下的執行程式碼為:
python -W ignore file.py去期待陌生,去擁抱驚喜。