np.seterr(invalid='raise')
来获取警告引发错误时的回溯信息(请参见此帖子)。
- 有没有通用的方法来追踪警告?
- 我能否让Python在引发警告时输出回溯信息?
np.seterr(invalid='raise')
来获取警告引发错误时的回溯信息(请参见此帖子)。
通过将代码赋值给warnings.showwarning
,您可以获得所需内容。 警告模块文档本身就建议您这样做,所以您并不是被源代码的黑暗面所诱惑。 :)
您可以通过将代码赋值给
warnings.showwarning
替换此函数为另一种实现。
您可以定义一个新函数,该函数执行warning.showwarning
通常所执行的操作,并添加了打印栈的功能。然后将其替换为原始函数:
import traceback
import warnings
import sys
def warn_with_traceback(message, category, filename, lineno, file=None, line=None):
log = file if hasattr(file,'write') else sys.stderr
traceback.print_stack(file=log)
log.write(warnings.formatwarning(message, category, filename, lineno, line))
warnings.showwarning = warn_with_traceback
在此之后,每个警告都将打印堆栈跟踪和警告消息。但是请注意,如果警告被忽略,因为它不是第一个,那么什么也不会发生,所以你仍然需要执行:After this, every warning will print the stack trace as well as the warning message. Take into account, however, that if the warning is ignored because it is not the first one, nothing will happen, so you still need to execute:
warnings.simplefilter("always")
您可以通过warning
模块的过滤器获得与numpy.seterr
相似的控制。
如果您想让Python每次触发警告时都报告,而不仅仅是第一次,可以添加类似以下代码的内容:
import warnings
warnings.simplefilter("always")
通过传入不同的字符串作为参数,您可以获得其他行为。使用相同的函数,您还可以针对引发警告的模块、它们提供的消息、警告类、引起警告的代码行等指定不同的警告行为。
您可以在模块文档中查看列表。
例如,您可以将所有警告设置为引发异常,但应完全忽略DeprecationWarnings
:
import warnings
warnings.simplefilter("error")
warnings.simplefilter("ignore", DeprecationWarning)
这种方式可以为每个警告抛出的错误获取完整的回溯(仅第一个,因为执行将停止...但您可以逐个解决它们,并创建过滤器以忽略您不想再次听到的警告..。
-W
标志,并且可以使用以下命令运行:pytest ... -W error
(文档:https://docs.pytest.org/en/stable/warnings.html)。根据详细程度,会显示类似于任何其他测试失败的回溯。 - KyleKingwarnings.filterwarnings()
将选定的警告转换为异常并获取回溯。最小工作示例如下所示:import warnings
warnings.filterwarnings(
action='error', message='',
category=RuntimeWarning
)
import warnings
warnings.filterwarnings(
'error', 'DateTimeField .* received a naive datetime',
RuntimeWarning, 'django.db.models.fields'
)
stacklevel
参数。当第三方警告被深埋在调用堆栈中时,这可能特别有帮助:将警告设置为stacklevel=2
,查看回溯信息,在必要时进行更改,恢复/删除stacklevel
到原始状态。
例如:
warnings.warn("It's dangerous to go alone! Take this.", stacklevel=2)
记录警告的选项,最小化对程序流程的干扰。
获取回溯信息而不触发错误:
import warnings
import traceback
warnings.filterwarnings("error") # Treat warnings as errors
try:
your_code()
except Warning:
print(traceback.format_exc()) # print traceback
warnings.resetwarnings() # Back to default behavior
except
块中执行它,这时忽略警告,因为您已经得到了其回溯:import warnings
import traceback
warnings.filterwarnings("error") # Treat warnings as errors
try:
your_code()
except Warning:
print(traceback.format_exc()) # print traceback
warnings.filterwarnings("ignore") # ignore warnings
your_code() # Execute either way (same code or alternative code)
warnings.resetwarnings() # Back to default behavior