目录:
warnings 模块是用于向用户发出非致命警报的重要工具,它允许程序在遇到某些不理想但又不至于引发异常并终止程序的情况时,向用户发出提示。
与异常不同,警告旨在提醒用户注意程序中的某些条件,例如使用了已过时的模块或存在可疑的语法,而程序本身可以继续执行。
这个模块为框架和库的开发者提供了一种优雅的方式来标记即将废弃的功能或潜在问题,是Python生态中不可或缺的调试与兼容性维护机制。
所有警告类别都继承自 Exception 的子类 Warning,Python 内置了多种警告类别,以满足不同场景的需求。
用户可以通过继承这些内置类别来定义自己的警告类别,以实现更精细化的警告控制。
警告过滤器是控制警告是否被显示、忽略或转为异常的核心机制。它维护着一个有序的规则列表,每条规则是一个包含动作(action)、消息匹配模式(message)、警告类别(category)、模块名(module)和行号(lineno)的元组。
当一个警告被触发时,它会依次与过滤器列表中的规则进行匹配,第一个匹配的规则将决定其最终命运。
动作(action)的可选值包括:
warnings.warn(message, category=None, stacklevel=1, source=None)
这是最常用的函数,用于触发一条警告。
warnings.filterwarnings(action, message=’’, category=Warning, module=’’, lineno=0, append=False)
用于向警告过滤器列表中添加一条规则,提供了最精细的控制能力。
可以通过 message(正则表达式,不区分大小写)和 module(正则表达式,区分大小写)参数来匹配特定的警告文本或模块,从而实现高度定制化的过滤。
warnings.simplefilter(action, category=Warning, lineno=0, append=False)
这是 filterwarnings() 的一个简化版本,它插入的过滤器会匹配任何模块中的任何消息,只要类别和行号匹配即可,使用起来更为便捷。
warnings.resetwarnings() 重置警告过滤器,清除所有通过 filterwarnings() 或 simplefilter() 添加的规则,以及命令行 -W 选项的效果,恢复到解释器的默认状态。
warnings.catch_warnings(record=False, module=None)
这是一个上下文管理器,用于在代码块内临时改变警告处理行为。
进入上下文管理器时,它会复制当前的警告过滤器和 showwarning() 函数,并在退出时恢复原状。当 record=True 时,它会返回一个列表,记录在上下文中触发的所有警告对象,这对于测试代码中触发的警告非常有用。
import warnings
warnings.warn("这是一个用户警告信息")
# 默认会触发一个UserWarning
import warnings
def deprecated_function():
warnings.warn("此函数已废弃,请使用 new_function 替代", DeprecationWarning, stacklevel=2)
# 调用此函数时,警告信息会指向调用deprecated_function()的代码行,而非函数内部。
在数据分析或导入大量第三方库时,常会遇到不重要的 DeprecationWarning 或 FutureWarning,可以全局忽略它们以保持输出整洁。
import warnings
warnings.filterwarnings('ignore', category=DeprecationWarning)
warnings.filterwarnings('ignore', category=FutureWarning)
在开发或测试阶段,有时需要确保某些警告被严肃对待,可以将其提升为异常。
import warnings
warnings.simplefilter('error', category=DeprecationWarning) # 将 DeprecationWarning 转为异常
try:
# 调用会触发DeprecationWarning的代码
pass
except DeprecationWarning as e:
print(f"捕获到废弃警告异常: {e}")
如果只想在特定代码段(如使用已知的废弃 API)中屏蔽警告,而不影响全局设置,可以使用上下文管理器。
import warnings
def using_old_api():
with warnings.catch_warnings():
warnings.simplefilter("ignore")
# 此代码块内触发的所有警告将被忽略
# ... 调用旧API的代码 ...
使用 catch_warnings(record=True) 可以捕获并验证代码触发的警告,是单元测试中的常用技巧。
import warnings
def function_that_warns():
warnings.warn("预期中的警告", UserWarning)
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
function_that_warns()
assert len(w) == 1
assert issubclass(w[-1].category, UserWarning)
assert "预期中的警告" in str(w[-1].message)
↶ 返回首页 ↶