问题:在Python中,如何将警告视为异常?
我在python代码中使用的第三方库(用C编写)正在发出警告。我希望能够使用try
except
语法正确处理这些警告。有没有办法做到这一点?
A third-party library (written in C) that I use in my python code is issuing warnings. I want to be able to use the try
except
syntax to properly handle these warnings. Is there a way to do this?
回答 0
引用python手册(27.6.4。Testing Warnings):
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)
To quote from the python handbook (27.6.4. Testing Warnings):
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)
回答 1
要将警告作为错误处理,只需使用以下命令:
import warnings
warnings.filterwarnings("error")
之后,您将能够捕获与错误相同的警告,例如,它将起作用:
try:
some_heavy_calculations()
except RuntimeWarning:
import ipdb; ipdb.set_trace()
PS添加了此答案,因为注释中的最佳答案包含拼写错误:filterwarnigns
而不是filterwarnings
。
To handle warnings as errors simply use this:
import warnings
warnings.filterwarnings("error")
After this you will be able to catch warnings same as errors, e.g. this will work:
try:
some_heavy_calculations()
except RuntimeWarning:
import ipdb; ipdb.set_trace()
P.S. Added this answer because the best answer in comments contains misspelling: filterwarnigns
instead of filterwarnings
.
回答 2
如果只希望脚本在警告上失败,则可以使用:
python -W error foobar.py
If you just want you script to fail on warnings you can invoke python
with the -W
argument:
python -W error foobar.py
回答 3
这是一个变体,可让您更清楚地了解如何仅使用自定义警告。
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)
Here’s a variation that makes it clearer how to work with only your custom warnings.
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)
回答 4
在某些情况下,您需要使用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
In some cases, you need use ctypes to turn warnings into errors. For example:
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