比较自定义warnings.showwarning

时间:2017-03-23 04:07:51

标签: python python-3.x warnings

当我看到一个非常具体的警告时,我正在尝试执行自定义操作。警告为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',因此第二行应该是Trueif而不是{{1}应该执行。但是,由于某种原因,似乎两个字符串不相同。

为什么会这样?为什么“自定义操作”else未被触发?

我尝试在脚本中用print('Doing a thing here')替换所有三次出现的'Skipping SYSTEM_VARIABLE record',以消除拼写错误的可能性。结果完全相同。

我在CentOS 7服务器上使用Anaconda 2.4.0上的Python 3.5.2,因此str与unicode应该不是问题。

1 个答案:

答案 0 :(得分:0)

在发布后的几分钟内找出预感的答案:

比较失败的原因是message不是字符串,而是实际警告对象,其字符串表示(通过str)恰好是警告消息。

额外的打印输出print(type(message))证明了这一事实:

<class 'UserWarning'>

正确的比较是str(message) == 'Skipping SYSTEM_VARIABLE record'

我保留此问题并回答的唯一原因是warnings.showwarning的文档中似乎没有任何内容可以明确描述此行为。