Skip to content

Python 中的警告处理

在修复 BUG 时发现 Python 会报出下种警告信息:

UnicodeWarning: Unicode unequal comparison failed to convert both arguments to Unicode - interpreting them as being unequal

这种问题大多是在对比文字是产生的,解决方法有两种: 1. 都转换成Unicode进行比较 2. 在代码开头引入 from __future__ import unicode_literals

在此,不讨论产生该问题的原因,仅仅讨论在 Python 中,警告信息的处理。

FBI WARNING

甚至大多数人都不会在意 FBI WARNING ,程序的警告更不会有人在意了。但在项目中,运行时没有警告是一个基本礼貌。

因为 Warning 和 BUG 有着本质的区别,所以异常捕获是无法抓取警告消息的。是否有某种方式可以使异常捕获时捕获到警告?

答案是有。

比如前文中提到的 UnicodeWarning,就可以使用 Python 提供的 warning 库进行过滤。

import warnings
warnings.filterwarnings(action='error', category=UnicodeWarning)

这样,原本不应该被捕获的警告信息也会被捕获到。

而且,在执行 Python 脚本是也有类似的办法捕获。

通常情况下,执行 Python 脚本的方法就是在命令行执行。

python action.py

但是 Python 解释器提供了丰富的参数,查看 Python 的 man 手册,会发现 -W 参数描述信息如下:

-W argument Warning control. Python sometimes prints warning message to sys.stderr. A typical warning message has the following form: file:line: category: message. By default, each warning is printed once for each source line where it occurs. This option controls how often warnings are printed. Multiple -W options may be given; when a warning matches more than one option, the action for the last matching option is performed. Invalid -W options are ignored (a warning message is printed about invalid options when the first warning is issued). Warnings can also be controlled from within a Python program using the warnings module.

The simplest form of argument is one of the following action strings (or a unique abbreviation): ignore to ignore all warnings; default to explicitly request the default behavior (printing each warning once per source line); all to print a warning each time it occurs (this may generate many messages if a warning is triggered repeatedly for the same source line, such as inside a loop); module to print each warning only the first time it occurs in each module; once to print each warning only the first time it occurs in the program; or error to raise an exception instead of printing a warning message.

The full form of argument is action:message:category:module:line. Here, action is as explained above but only applies to messages that match the remaining fields. Empty fields match all values; trailing empty fields may be omitted. The message field matches the start of the warning message printed; this match is case-insensitive. The category field matches the warning category. This must be a class name; the match test whether the actual warning category of the message is a subclass of the specified warning category. The full class name must be given. The module field matches the (fully-qualified) module name; this match is case-sensitive. The line field matches the line number, where zero matches all line numbers and is thus equivalent to an omitted line number.

其大体意义为使用 -W 参数可以对警告进行相关的处理。为了达到和使用 warning 库的相同效果,在执行脚本时也可以使用:

python -W error action.py