在 Python 中,如何将警告视为异常?

问题描述 投票:0回答:8

我在 python 代码中使用的第三方库(用 C 编写)发出警告。我希望能够使用

try
except
语法来正确处理这些警告。有办法做到这一点吗?

python exception warnings
8个回答
249
投票

要将警告作为错误处理,只需使用以下命令:

import warnings
warnings.filterwarnings("error")

此后,您将能够捕获与错误相同的警告,例如这会起作用:

try:
    some_heavy_calculations()
except RuntimeWarning:
    breakpoint()

您还可以通过运行以下命令来重置警告行为:

warnings.resetwarnings()

附注添加此答案是因为评论中的最佳答案包含拼写错误:

filterwarnigns
而不是
filterwarnings


75
投票

引用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)

43
投票

如果您只是希望脚本在出现警告时失败,您可以使用

python 参数调用 
-W
:

python -W error foobar.py

24
投票

这里有一个变体,可以让您更清楚地了解如何仅使用自定义警告。

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)

12
投票

扩展 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

7
投票

捕获所有警告可能会出现问题。您可以捕获特定的警告。例如,我需要捕捉枕头警告:

import warnings
warnings.filterwarnings("error", category=Image.DecompressionBombWarning)

def process_images():
  try:
    some_process()

  except Image.DecompressionBombWarning as e:
    print(e)

6
投票

在某些情况下,您需要使用ctypes将警告转化为错误。例如:

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

1
投票

为了完整起见,您还可以导出环境变量:

PYTHONWARNINGS=error /usr/bin/run_my_python_utility
© www.soinside.com 2019 - 2024. All rights reserved.