我在我的Python代码中使用的第三方库(用C语言编写)正在发出警告。我希望能够使用try
except
语法来正确处理这些警告。有没有办法做到这一点?
要将警告视为错误,只需使用以下代码:
-Werror
import warnings
warnings.filterwarnings("error")
完成后,您将能够像处理错误一样捕获警告,例如:
try:
some_heavy_calculations()
except RuntimeWarning:
breakpoint()
您也可以通过运行以下命令来重置警告的行为:
warnings.resetwarnings()
补充说明:添加此答案是因为评论中最佳答案存在拼写错误:filterwarnigns
而非 filterwarnings
。
filterwarnings
即可捕获警告,它会自动生效。 - naught101引用自Python手册 (27.6.4. 测试警告):
import warnings
def fxn():
warnings.warn("deprecated", DeprecationWarning)
with warnings.catch_warnings(record=True) as w:
# Cause all warnings to always be triggered.
warnings.simplefilter("always")
# Trigger a warning.
fxn()
# Verify some things
assert len(w) == 1
assert issubclass(w[-1].category, DeprecationWarning)
assert "deprecated" in str(w[-1].message)
try
和except
语法。 - Unapiedrafxn()
没有返回警告,则 w
将为空列表。如果 w
是空列表(即 []
),则运行代码将导致以下错误: IndexError: list index out of range
。如果您只是想格式化或检查捕获的警告的属性,则最好使用 for 循环:for x in w: print(f'{x.category.__name__}: {str(x.message)}')
。 - Steven M. Mortimer如果你只想让你的脚本在警告时失败,你可以使用-W
参数来调用python
:
python -W error foobar.py
python -W error::RuntimeWarning foobar.py
。 - Paul Price这是一种变体,使得仅使用自定义警告更加清晰易懂。
import warnings
with warnings.catch_warnings(record=True) as w:
# Cause all warnings to always be triggered.
warnings.simplefilter("always")
# Call some code that triggers a custom warning.
functionThatRaisesWarning()
# ignore any non-custom warnings that may be in the list
w = filter(lambda i: issubclass(i.category, UserWarning), w)
if len(w):
# do something with the first warning
email_admins(w[0].message)
在niekas的回答基础上进行拓展,但使用catch_warnings
上下文管理器,在上下文退出后将警告行为重置为默认值:
import warnings
with warnings.catch_warnings():
warnings.simplefilter("error")
# Code in this block will raise exception for a warning
# Code in this block will have default warning behaviour
捕获所有警告可能存在问题。您可以捕获特定的警告。例如,我需要捕获一个Pillow警告:
import warnings
warnings.filterwarnings("error", category=Image.DecompressionBombWarning)
def process_images():
try:
some_process()
except Image.DecompressionBombWarning as e:
print(e)
str(b'test') # no error
import warnings
warnings.simplefilter('error', BytesWarning)
str(b'test') # still no error
import ctypes
ctypes.c_int.in_dll(ctypes.pythonapi, 'Py_BytesWarningFlag').value = 2
str(b'test') # this raises an error
warnings.simplefilter('error')
,你将无法获得日志中看到的警告的回溯信息,而是会得到之前过滤的警告的回溯信息。如果你有一些 CLI 调用,使用 simplefilter
也是最快的方法来得到你的答案。 - AlanSE为了完整起见,您还可以导出环境变量:
PYTHONWARNINGS=error /usr/bin/run_my_python_utility
warnings.filterwarnings
正好符合您的需求,我不明白您对它有什么问题? - Rosh Oxymoronwarnings.filterwarnings('error')
可以解决问题。我找不到最初提出此解决方案的答案。 - Boris Gorelik