为什么循环中只有一个警告?

43 投票
4 回答
10131 浏览
提问于 2025-04-17 23:58

我想在一个循环中,每当发现一个问题就发出警告,但现在只在第一次发现问题时发出一次警告。比如:

import warnings

for i in range(10):
   print i
   warnings.warn('this is a warning message')

我期望得到:

0
UserWarning: this is a warning message
1
UserWarning: this is a warning message
2
UserWarning: this is a warning message
3
UserWarning: this is a warning message
4

但实际结果是:

0
__main__:4: UserWarning: this is a warning message
1
2
3
4

为什么我只收到一次警告?我该怎么做才能在每次循环中都收到警告呢?

4 个回答

3

默认的过滤器会阻止你的警告出现多次。如果你想让警告多次出现,可以使用simplefilter来覆盖这个过滤器。

import warnings

warnings.simplefilter("always")
for i in range(10):
    print i
    warnings.warn('this is a warning message')
6

之前的回答里已经提到,默认情况下,每个警告在出现的每个源文件中只会打印一次。不过,你可以很简单地通过命令行来改变这个设置。只需要在命令行中输入 python -W all 来启动解释器就可以了:

$ python -W all
Python 2.7.6 (default, Mar 16 2014, 23:42:21)
[GCC 4.5.3] on netbsd6
Type "help", "copyright", "credits" or "license" for more information.
>>> import warnings
>>> for i in range(10):
   print i
   warnings.warn('this is a warning message')... ...
...
0
__main__:3: UserWarning: this is a warning message
1
__main__:3: UserWarning: this is a warning message
2
__main__:3: UserWarning: this is a warning message
3
__main__:3: UserWarning: this is a warning message
4
__main__:3: UserWarning: this is a warning message
5
__main__:3: UserWarning: this is a warning message
6
__main__:3: UserWarning: this is a warning message
7
__main__:3: UserWarning: this is a warning message
8
__main__:3: UserWarning: this is a warning message
9
__main__:3: UserWarning: this is a warning message
>>>
10

来自warnings模块文档的内容:

对于同一个地方的特定警告,通常会抑制重复出现的警告。

这是故意设计的。

如果你希望你的信息总是被打印出来,我建议不要使用warnings模块;你可以重置过滤器(使用warnings.resetwarnings()),但这并不推荐,因为这样会丢掉用户自己设置的过滤器。你可以使用warnings.simplefilter()函数添加一个明确的过滤器,让信息总是被允许显示:

warnings.simplefilter('always', UserWarning)

但我更建议直接写到sys.stderr

63

这是故意这样设计的。你可以查看文档,地址是 https://docs.python.org/3/library/warnings.html

对于同一个地方的特定警告,通常会抑制重复的警告信息。

如果你想改变这种行为,可以通过添加一个过滤器,使用关键词 "always",就像这样:

import warnings

warnings.simplefilter('always', UserWarning)
for i in range(10):
    print(i)
    warnings.warn('this is a warning message')

撰写回答