获取警告的追溯


70

在numpy中,我们可以np.seterr(invalid='raise')获取对引发错误的警告的回溯(请参见此文章)。

  • 是否有跟踪警告的一般方法?
  • 发出警告时,我可以使python进行追溯吗?


我想所有答案都无法让您满意。您能再解释一下您需要什么吗?:)
mgab 2014年

@mgab的问题是,很难找到警告,因为它不随信息一起被调用。使所有警告变为致命,程序将在第一个警告(在某处调用)之后退出。我想知道,是否有办法告诉python,在引发警告时打印回溯,或以其他任何方式确定警告的来源。
2014年

好吧,如果将警告引发为错误,则它确实会在第一个警告处停止,但是您应该获得一个追溯,报告该错误(或警告最初)发生的位置的完整堆栈。但是我同意这不是最佳选择,特别是如果您的脚本需要一段时间的话...我用我认为是更好解决您问题的答案更新了答案
mgab 2014年

Answers:


102

通过分配给,您可以获得想要的东西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

此后,每个警告将打印堆栈跟踪以及警告消息。但是请考虑到,如果由于警告不是第一个警告而被忽略,则不会发生任何事情,因此您仍然需要执行以下操作:

warnings.simplefilter("always")

您可以numpy.seterr通过warning模块的过滤器获得类似的控件

如果您想要的是python在每次触发警告时(不仅是第一次)都报告每个警告,则可以包含以下内容:

import warnings
warnings.simplefilter("always")

您可以通过传递不同的字符串作为参数来获得其他行为。使用相同的功能,您还可以根据引发警告的模块,警告提供的消息,警告类,引起警告的代码行等为警告指定不同的行为...

您可以在模块文档中查看列表

例如,您可以设置所有警告以引发异常,但DeprecationWarnings应该完全忽略这些警告:

import warnings
warnings.simplefilter("error")
warnings.simplefilter("ignore", DeprecationWarning)

这样,您可以对引发为错误的每个警告进行完整的追溯(只有第一个警告,因为执行将停止...但是您可以一个一个地解决它们,并创建一个过滤器以忽略那些您不想听到的警告大约...


3
这样有用的答案。这些年来,@ embert应该真正将其标记为答案。
beldaz

28

像这样运行程序

python -W error myprogram.py

这会使所有警告变为致命,请参阅此处以获取更多信息。


15
这样可行。但是,有没有一种方法可以强制python在每个警告上打印回溯。问题是,当在导入过程中出现弃用警告时,使用此选项的程序将已经失败。
2014年

如果需要这是一个单元测试(或模块),则可以执行以下操作:python -W error -m pytest
Omry Yadan

1

您可以使用warnings.filterwarnings()将选定的警告转换为异常并进行如下追溯:

import warnings
warnings.filterwarnings(
    'error', 'DateTimeField .* received a naive datetime',
    RuntimeWarning, 'django.db.models.fields'
)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.