warnings
warnings 模块用于向开发者发出非致命性的警告信息。几乎所有成熟的 Python 库(numpy、torch、transformers)都依赖此模块来管理弃用通知和兼容性警告。理解它是参与 CPython 开发和编写生产级库的前提。
发出警告
import warnings
def old_api():
warnings.warn("old_api() 已弃用,请使用 new_api()", DeprecationWarning, stacklevel=2)
return "old result"
def new_api():
return "new result"
result = old_api()
# <stdin>:1: DeprecationWarning: old_api() 已弃用,请使用 new_api()
stacklevel 参数
stacklevel=2 让警告指向调用 old_api() 的那一行,而非 warnings.warn() 所在行。这是库开发中的常见模式。
警告类别
import warnings
# 内置警告类别
warnings.warn("即将弃用", PendingDeprecationWarning)
warnings.warn("已弃用", DeprecationWarning)
warnings.warn("运行时问题", RuntimeWarning)
warnings.warn("用户级别警告", UserWarning) # 默认类别
warnings.warn("资源未关闭", ResourceWarning)
warnings.warn("未来行为变更", FutureWarning)
# 自定义警告类别
class APIChangedWarning(UserWarning):
pass
warnings.warn("API 响应格式已变更", APIChangedWarning)
控制警告行为
import warnings
# 将所有 DeprecationWarning 转为错误
warnings.filterwarnings("error", category=DeprecationWarning)
try:
warnings.warn("deprecated!", DeprecationWarning)
except DeprecationWarning as e:
print(f"捕获到: {e}")
# 忽略特定模块的警告
warnings.filterwarnings("ignore", module="noisy_module")
# 只显示一次
warnings.filterwarnings("once", category=UserWarning)
# 重置所有过滤器
warnings.resetwarnings()
上下文管理器
import warnings
# 临时捕获警告
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
warnings.warn("test warning 1", UserWarning)
warnings.warn("test warning 2", DeprecationWarning)
print(f"捕获到 {len(w)} 个警告")
for warning in w:
print(f" {warning.category.__name__}: {warning.message}")
# 临时忽略警告
with warnings.catch_warnings():
warnings.simplefilter("ignore")
warnings.warn("这不会显示")
print("上下文外恢复原有行为")
在库开发中的最佳实践
import warnings
import functools
def deprecated(replacement=None):
"""通用弃用装饰器"""
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
msg = f"{func.__name__}() 已弃用"
if replacement:
msg += f",请使用 {replacement}()"
warnings.warn(msg, DeprecationWarning, stacklevel=2)
return func(*args, **kwargs)
return wrapper
return decorator
@deprecated(replacement="load_model_v2")
def load_model(path):
return f"model from {path}"
model = load_model("/tmp/model.pt")
命令行控制
# 将所有警告变为错误(适合 CI)
python -W error script.py
# 忽略弃用警告
python -W ignore::DeprecationWarning script.py
# 显示所有警告
python -W all script.py
# 环境变量方式
PYTHONWARNINGS=error python script.py
为什么 AI 开发者需要理解 warnings
使用 transformers、torch、numpy 时你一定见过大量警告信息。理解 warnings 模块可以:
- 在训练脚本中精确控制哪些警告需要关注
- 在自己的库中正确使用弃用机制
- 在 CI 中将警告变为错误,及早发现兼容性问题