1. 程式人生 > 其它 >python之warnings模組(warnings.filterwarnings("ignore")程式碼解析)

python之warnings模組(warnings.filterwarnings("ignore")程式碼解析)

前言

①Python通過呼叫warnings 模組中定義的warn() 函式來發出警告。

②警告訊息通常用於提示使用者一些錯誤或者過時的用法,當這些情況發生時我們不希望丟擲異常或者直接退出程式。

③警告訊息通常寫入sys.stderr,對警告的處理方式可以靈活的更改,例如忽略或者轉變為為異常。警告的處理可以根據警告類別,警告訊息的文字和發出警告訊息的源位置而變化。對相同源位置的特定警告的重複通常被抑制。

④警告控制分為兩個階段:首先,警告被觸發時,確定是否應該發出訊息(警告過濾器);接下來,如果要發出訊息,則使用使用者可設定的鉤子來格式化和列印訊息。

警告過濾器可以用來控制是否發出警告訊息,警告過濾器是一些匹配規則和動作的序列。可以通過呼叫filterwarnings()

將規則新增到過濾器,並通過呼叫resetwarnings()將其重置為預設狀態。

警告訊息的輸出是通過呼叫showwarning() 函式來完成的,其可以被覆蓋;該函式的預設實現通過呼叫formatwarning() 格式化訊息,這也可以由自定義實現使用。

警告類別

內建警告型別:

可以通過繼承內建警告型別實現自定義的警告型別警告型別必須始終是Warning類的子類

警告過濾器

警告過濾器用於控制警告的行為,如忽略,顯示或轉換為錯誤(引發異常)

警告過濾器維護著一個有序的過濾規則列表,匹配規則用於確定如何處理警告,任何特定警告都將依次與列表中的每個過濾規則匹配,直到找到匹配為止。過濾規則型別為一個元組 (action,message,category,module,lineno);

其中:

  • action為以下值:
  • message是包含正則表示式的字串,警告訊息的開始必須匹配,不區分大小寫
  • category是一個警告型別(必須是 Warning 的子類)
  • module是包含模組名稱的正則表示式字串,區分大小寫
  • lineno是一個整數,警告發生的行號,為 0 則匹配所有行號

預設警告過濾器

預設情況下,Python 設定了幾個警告過濾器,可以通過 -W 命令列選項和呼叫 filterwarnings()函式來覆蓋它們。

  • DeprecationWarningPendingDeprecationWarningImportWarning 被預設忽略。
  • 除非-b選項給出一次或兩次,否則忽略 BytesWarning
    ;在這種情況下,此警告或者被輸出(-b)或者變成異常(-bb)。
  • 除非 Python 是在除錯模式下構建的,否則將忽略 ResourceWarning

在 3.2 版中的調整: 除PendingDeprecationWarning 之外,預設情況下將忽略DeprecationWarning

可用函式

①warn

warnings.warn(message, category=None, stacklevel=1, source=None)

觸發異常。category引數預設為 UserWarningmessage引數為警告訊息,可以是 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
去期待陌生,去擁抱驚喜。