比较自定义 warnings.showwarning 中的消息字符串
Comparing message strings in custom warnings.showwarning
当我看到非常具体的警告时,我正在尝试执行自定义操作。警告是带有消息 'Skipping SYSTEM_VARIABLE record'
的 UserWarning
。我希望所有其他警告,包括所有其他带有不同消息的 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
而不是 else
应该被执行。但是,由于某些原因,这两个字符串似乎并不相同。
为什么会这样?为什么 "custom action" print('Doing a thing here')
没有被触发?
我已尝试将脚本中出现的所有三个 'Skipping SYSTEM_VARIABLE record'
替换为 'a'
以消除打字错误的可能性。发生完全相同的结果。
我在 CentOS 7 服务器上的 Anaconda 2.4.0 上使用 Python 3.5.2,因此 str 与 unicode 应该不是问题。
发帖几分钟后凭直觉找出答案:
比较失败的原因是message
不是字符串,而是实际的警告对象,其字符串表示(通过str
)恰好只是警告消息。
额外的打印输出,print(type(message))
证明了这一事实:
<class 'UserWarning'>
正确的比较是str(message) == 'Skipping SYSTEM_VARIABLE record'
。
我保留这个问题和答案的唯一原因是 warnings.showwarning
的文档中似乎没有任何内容来明确描述此行为。
当我看到非常具体的警告时,我正在尝试执行自定义操作。警告是带有消息 'Skipping SYSTEM_VARIABLE record'
的 UserWarning
。我希望所有其他警告,包括所有其他带有不同消息的 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
而不是 else
应该被执行。但是,由于某些原因,这两个字符串似乎并不相同。
为什么会这样?为什么 "custom action" print('Doing a thing here')
没有被触发?
我已尝试将脚本中出现的所有三个 'Skipping SYSTEM_VARIABLE record'
替换为 'a'
以消除打字错误的可能性。发生完全相同的结果。
我在 CentOS 7 服务器上的 Anaconda 2.4.0 上使用 Python 3.5.2,因此 str 与 unicode 应该不是问题。
发帖几分钟后凭直觉找出答案:
比较失败的原因是message
不是字符串,而是实际的警告对象,其字符串表示(通过str
)恰好只是警告消息。
额外的打印输出,print(type(message))
证明了这一事实:
<class 'UserWarning'>
正确的比较是str(message) == 'Skipping SYSTEM_VARIABLE record'
。
我保留这个问题和答案的唯一原因是 warnings.showwarning
的文档中似乎没有任何内容来明确描述此行为。