<p>读了几遍文档,翻了几遍源代码和外壳,我想我已经找到了。文档可能会有所改进,以便更清楚地了解行为是什么。</p>
<p>警告模块在warnings registry保存一个注册表,以跟踪显示了哪些警告。如果在设置“error”筛选器之前注册表中没有列出警告(消息),则对warn()的任何调用都不会导致将消息添加到注册表中。此外,在第一次调用warn之前,似乎不会创建警告注册表:</p>
<pre><code>>>> 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__
{}
</code></pre>
<p>现在,如果忽略警告,它们将被添加到警告注册表:</p>
<pre><code>>>> 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
</code></pre>
<p>因此,错误筛选器将只应用于警告注册表中尚未出现的警告。要使代码正常工作,您需要在使用上下文管理器之后(或者通常在使用忽略筛选器并需要prev之后的任何时候)从警告注册表中清除相应的条目。用于提取错误筛选器的消息)。似乎有点不自然。。。</p>