В Python, как поймать предупреждения, как если бы они были исключениями?
сторонняя библиотека (написанная на C), которую я использую в своем коде python, выдает предупреждения. Я хочу иметь возможность использовать try
except
синтаксис для правильной обработки этих предупреждений. Есть ли способ сделать это?
5 ответов
цитата из руководства 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)
для обработки предупреждений как ошибок просто используйте это:
import warnings
warnings.filterwarnings("error")
после этого вы сможете поймать предупреждения так же, как ошибки, например, это будет работать:
try:
some_heavy_calculations()
except RuntimeWarning:
import ipdb; ipdb.set_trace()
P. S. добавил этот ответ, потому что лучший ответ в комментарии содержится опечатка: filterwarnigns
вместо filterwarnings
.
вот вариант, который делает его более ясным, как работать только с вашими пользовательскими предупреждениями.
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)
Если вы просто хотите, чтобы ваш скрипт терпел неудачу при предупреждениях, вы можете использовать:
python -W error foobar.py
в некоторых случаях вам нужно использовать 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