gpt4 book ai didi

python - 如何禁用然后重新启用警告?

转载 作者:太空狗 更新时间:2023-10-29 17:39:32 25 4
gpt4 key购买 nike

我正在为 Python 库编写一些单元测试,并希望将某些警告作为异常引发,我可以使用 simplefilter 轻松做到这一点。功能。但是,对于一个测试,我想禁用警告,运行测试,然后重新启用警告。

我使用的是 Python 2.6,所以我应该能够使用 catch_warnings 来做到这一点上下文管理器,但它似乎对我不起作用。即使失败了,我也应该可以调用 resetwarnings然后重新设置我的过滤器。

这是一个说明问题的简单示例:

>>> import warnings
>>> warnings.simplefilter("error", UserWarning)
>>>
>>> def f():
... warnings.warn("Boo!", UserWarning)
...
>>>
>>> f() # raises UserWarning as an exception
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in f
UserWarning: Boo!
>>>
>>> f() # still raises the exception
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in f
UserWarning: Boo!
>>>
>>> with warnings.catch_warnings():
... warnings.simplefilter("ignore")
... f() # no warning is raised or printed
...
>>>
>>> f() # this should raise the warning as an exception, but doesn't
>>>
>>> warnings.resetwarnings()
>>> warnings.simplefilter("error", UserWarning)
>>>
>>> f() # even after resetting, I'm still getting nothing
>>>

谁能解释一下我如何才能做到这一点?

编辑:显然这是一个已知错误:http://bugs.python.org/issue4180

最佳答案

通读文档几次并查看源代码和 shell 我想我已经弄明白了。文档可能会改进以更清楚地说明行为是什么。

警告模块在 __warningsregistry__ 中保留一个注册表,以跟踪显示了哪些警告。如果在设置“错误”过滤器之前注册表中未列出警告(消息),则对 warn() 的任何调用都不会导致将消息添加到注册表中。此外,在第一次调用 warn 之前,似乎不会创建警告注册表:

>>> import warnings
>>> __warningregistry__
------------------------------------------------------------
Traceback (most recent call last):
File "<ipython console>", line 1, in <module>
NameError: name '__warningregistry__' is not defined

>>> warnings.simplefilter('error')
>>> __warningregistry__
------------------------------------------------------------
Traceback (most recent call last):
File "<ipython console>", line 1, in <module>
NameError: name '__warningregistry__' is not defined

>>> warnings.warn('asdf')
------------------------------------------------------------
Traceback (most recent call last):
File "<ipython console>", line 1, in <module>
UserWarning: asdf

>>> __warningregistry__
{}

现在如果我们忽略警告,它们将被添加到警告注册表中:

>>> warnings.simplefilter("ignore")
>>> warnings.warn('asdf')
>>> __warningregistry__
{('asdf', <type 'exceptions.UserWarning'>, 1): True}
>>> warnings.simplefilter("error")
>>> warnings.warn('asdf')
>>> warnings.warn('qwerty')
------------------------------------------------------------
Traceback (most recent call last):
File "<ipython console>", line 1, in <module>
UserWarning: qwerty

因此错误过滤器将仅适用于不在警告注册表中的警告。为了使您的代码正常工作,您需要在使用上下文管理器完成后(或者通常在您使用了忽略过滤器并希望使用 prev.used 消息之后的任何时间)从警告注册表中清除适当的条目被拾取错误过滤器)。好像有点不直观……

关于python - 如何禁用然后重新启用警告?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2390766/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com