当我看到一个非常具体的警告时,我正在尝试执行自定义操作。警告为UserWarning
,邮件为'Skipping SYSTEM_VARIABLE record'
。我希望所有其他警告(包括具有不同消息的所有其他UserWarning
)像往常一样传播并打印到stderr
。
我能找到的唯一方法是用自定义实现替换warnings.showwarning
,如下面的测试脚本所示:
import warnings
def showw(message, category, filename, lineno, file=None, line=None):
print(message, category, filename, lineno, file, line, sep='|')
print(message == 'Skipping SYSTEM_VARIABLE record')
print(category == UserWarning)
if category == UserWarning and message == 'Skipping SYSTEM_VARIABLE record':
print('Doing a thing here')
else:
original(message, category, filename, lineno, file=file, line=line)
original = warnings.showwarning
warnings.showwarning = showw
warnings.warn('Skipping SYSTEM_VARIABLE record')
此脚本打印出以下输出:
Skipping SYSTEM_VARIABLE record|<class 'UserWarning'>|x.py|15|None|None
False
True
x.py:15: UserWarning: Skipping SYSTEM_VARIABLE record
warnings.warn('Skipping SYSTEM_VARIABLE record')
我觉得这个输出很令人惊讶,因为第一行表明该消息实际上是'Skipping SYSTEM_VARIABLE record'
,因此第二行应该是True
,if
而不是{{1}应该执行。但是,由于某种原因,似乎两个字符串不相同。
为什么会这样?为什么“自定义操作”else
未被触发?
我尝试在脚本中用print('Doing a thing here')
替换所有三次出现的'Skipping SYSTEM_VARIABLE record'
,以消除拼写错误的可能性。结果完全相同。
我在CentOS 7服务器上使用Anaconda 2.4.0上的Python 3.5.2,因此str与unicode应该不是问题。
答案 0 :(得分:0)
在发布后的几分钟内找出预感的答案:
比较失败的原因是message
不是字符串,而是实际警告对象,其字符串表示(通过str
)恰好是警告消息。
额外的打印输出print(type(message))
证明了这一事实:
<class 'UserWarning'>
正确的比较是str(message) == 'Skipping SYSTEM_VARIABLE record'
。
我保留此问题并回答的唯一原因是warnings.showwarning
的文档中似乎没有任何内容可以明确描述此行为。