13

有没有办法__warningregistry__一次重置所有加载的功能?

我想强制使用“一次”过滤器过滤的所有警告再次显示。除了调用<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()函数也清除所有警告注册表,而不仅仅是当前的命名空间。

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

4

3 回答 3

6

该功能似乎并不直接存在于 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__()
于 2015-07-26T16:09:26.377 回答
2

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

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

于 2014-05-28T14:23:07.990 回答
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!")
于 2021-05-18T14:03:00.183 回答