让Python的`warnings.warn()`不提及自身
我的最简单例子是
#!/usr/bin/python3
import warnings
warnings.warn('Run Forest run!', stacklevel=2)
warnings.warn('Run Forest run!')
它会输出
sys:1: UserWarning: Run Forest run!
./file.py:6: UserWarning: Run Forest run!
warnings.warn('Run Forest run!')
第一行给我的信息太少了。第二行很完美,告诉我源文件和行号……但我想去掉多余的第三行。这样做可以吗?
3 个回答
2
如果你想捕捉异常或错误,并且希望同时看到你自己定义的警告信息和错误追踪信息,你可以使用 traceback.print_exc():
import traceback
import warnings
def _formatwarning(msg, *a):
try:
traceback.print_exc()
except:
pass
return str(msg)
warnings.formatwarning = _formatwarning
这样的话,warn("你的信息") 就会打印出错误追踪信息,而不会提到 warn() 这个函数本身的调用。
更新:在 Python 3.6 中,你需要把函数的定义改成:
def _formatwarning(message, category, filename, lineno, line='')
6
你看到“多余”的提示是因为如果你不提供 stacklevel
参数,默认的 stacklevel
是 1。这意味着它会告诉用户警告是从哪一行代码发出的,也就是你调用的警告函数 warnings.warn('Run Forest Run!')
。
如果你觉得这样不太好,可以使用 warnings.warn_explicit()
函数来进行自定义。
https://docs.python.org/3.1/library/warnings.html#available-functions
17
原来可以让 warnings.warn()
收集所有信息,然后只需要自定义信息的打印方式:
#!/usr/bin/python3
import warnings
def warning_on_one_line(message, category, filename, lineno, file=None, line=None):
return '%s:%s: %s: %s\n' % (filename, lineno, category.__name__, message)
warnings.formatwarning = warning_on_one_line
warnings.warn('Run Forest run!', stacklevel=2)
warnings.warn('Run Forest run!')
输出结果:
sys:1: UserWarning: Run Forest run!
./file.py:15: UserWarning: Run Forest run!
来源: 本周的Python模块