В 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