Python - 再次显示“一次”警告(重置所有警告注册表)

时间:2013-10-17 13:56:44

标签: python warnings

有没有办法立即重置所有已加载函数的__warningregistry__

我想强制所有使用'once'过滤器过滤的警告再次显示。除了在我加载的每个函数(包括那些属于导入模块的函数)上调用<func>.__globals__['__warningregistry__'].clear()之外,我没有办法做到这一点。

所以,我想要的是像warnings.clear()函数那样执行以下操作:

>>> import warnings
>>> warnings.warn('blah')
WARNING:root:blah ->UserWarning at ...
>>> warnings.warn('blah')
>>> warnings.clear()
>>> warnings.warn('blah')
WARNING:root:blah ->UserWarning at ...

我希望此warnings.clear()功能还清除所有警告注册表,而不仅仅是当前的名称空间。

这已经存在了吗?也许我错过了一些明显的东西,或者错误地使用了模块?

3 个答案:

答案 0 :(得分:5)

该功能似乎不直接存在于Python中。

但是,我需要为我自己的库的单元测试提供类似的功能,并编写了一个上下文管理器,它为整个进程备份警告注册表状态,清除它,然后在上下文完成后恢复它。

此处发布时间有点太长了,但我已将其作为解决python bug 21724的潜在起点提交,因此您应该可以直接从http://bugs.python.org/file40031/reset_warning_registry.py下载并使用

用法如下:

from reset_warning_registry import reset_warning_registry

with reset_warning_registry():
    ... do things with clear registry ...

# alternately, to just clear the warnings w/o restoring
reset_warning_registry().__enter__()

答案 1 :(得分:2)

我不相信这个功能存在,至少在2.7.6中不存在。我查看了warnings.py和_warnings.c,但我找不到任何可以用来执行此操作的内容。

我想也许你可以包装模块并覆盖warn()调用以将globals()['__ warningregistry__']放入列表中,并添加一个新的clear()函数来循环它并重置所有电话的注册表。

答案 2 :(得分:0)

我认为将过滤器设置为“始终”可以满足这种需求。

> cat warnme.py 
import warnings

for i in range(3):
    warnings.warn("oh noes!")

> python warnme.py 
warnme.py:4: UserWarning: oh noes!
warnings.warn("oh noes!")

> cat warnme2.py 
import warnings

warnings.simplefilter("always")
for i in range(3):
    warnings.warn("oh noes!")

> python warnme2.py 
warnme2.py:5: UserWarning: oh noes!
warnings.warn("oh noes!")
warnme2.py:5: UserWarning: oh noes!
warnings.warn("oh noes!")
warnme2.py:5: UserWarning: oh noes!
warnings.warn("oh noes!")