Документация Python неофициальный перевод

warnings.md

239 строк · 26.1 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/3.0/library/warnings.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# `warnings` – Управление предупреждениями89Предупреждения обычно выводятся в ситуациях, когда полезно предупредить пользователя о некотором условии в программе, когда это условие (обычно) не требует возбуждения исключения и завершения программы. Например, может потребоваться выдать предупреждение, если программа использует устаревший модуль.1011Python programmers issue warnings by calling the [`warn()`](https://python-all.ru/3.0/library/warnings.html#warnings.warn) function defined in this module. (C programmers use [`PyErr_WarnEx`](https://python-all.ru/3.0/c-api/exceptions.html#PyErr_WarnEx); see [*Exception Handling*](https://python-all.ru/3.0/c-api/exceptions.html#exceptionhandling) for details).1213Предупреждения обычно выводятся в `sys.stderr`, но их обработку можно гибко настраивать – от полного игнорирования до превращения в исключения. Обработка предупреждений может различаться в зависимости от категории предупреждения (см. ниже), текста сообщения и места в исходном коде, где оно было вызвано. Повторные предупреждения из одного и того же места обычно подавляются.1415Управление предупреждениями состоит из двух этапов: сначала каждый раз при выдаче предупреждения определяется, должно ли сообщение быть выдано; затем, если сообщение должно быть выдано, оно форматируется и выводится с помощью настраиваемого пользователем перехватчика.1617Решение о том, нужно ли выдавать предупреждение, определяется фильтром предупреждений – последовательностью правил сопоставления и действий. Правила можно добавлять в фильтр, вызывая [`filterwarnings()`](https://python-all.ru/3.0/library/warnings.html#warnings.filterwarnings), и сбрасывать в исходное состояние вызовом [`resetwarnings()`](https://python-all.ru/3.0/library/warnings.html#warnings.resetwarnings).1819Вывод предупреждений на экран осуществляется вызовом [`showwarning()`](https://python-all.ru/3.0/library/warnings.html#warnings.showwarning), который можно переопределить; стандартная реализация этой функции форматирует сообщение, вызывая [`formatwarning()`](https://python-all.ru/3.0/library/warnings.html#warnings.formatwarning), которая также доступна для использования в пользовательских реализациях.2021## Категории предупреждений2223Существует ряд встроенных исключений, представляющих категории предупреждений. Такая категоризация полезна для фильтрации групп предупреждений. В настоящее время определены следующие классы категорий предупреждений:2425| Класс | Описание |26| --- | --- |27| [`Warning`](https://python-all.ru/3.0/library/exceptions.html#exceptions.Warning) | Это базовый класс всех категорий предупреждений. Он наследуется от [`исключения`](https://python-all.ru/3.0/library/exceptions.html#exceptions.Exception). |28| [`UserWarning`](https://python-all.ru/3.0/library/exceptions.html#exceptions.UserWarning) | Категория по умолчанию для [`warn()`](https://python-all.ru/3.0/library/warnings.html#warnings.warn). |29| [`DeprecationWarning`](https://python-all.ru/3.0/library/exceptions.html#exceptions.DeprecationWarning) | Базовая категория для предупреждений об устаревших функциях. |30| [`SyntaxWarning`](https://python-all.ru/3.0/library/exceptions.html#exceptions.SyntaxWarning) | Базовый тип для предупреждений о сомнительных синтаксических особенностях. |31| [`RuntimeWarning`](https://python-all.ru/3.0/library/exceptions.html#exceptions.RuntimeWarning) | Базовая категория для предупреждений о сомнительных возможностях времени выполнения. |32| [`FutureWarning`](https://python-all.ru/3.0/library/exceptions.html#exceptions.FutureWarning) | Базовая категория для предупреждений о конструкциях, которые в будущем изменят свою семантику. |33| [`PendingDeprecationWarning`](https://python-all.ru/3.0/library/exceptions.html#exceptions.PendingDeprecationWarning) | Базовая категория для предупреждений о возможностях, которые будут объявлены устаревшими в будущем (игнорируется по умолчанию). |34| [`ImportWarning`](https://python-all.ru/3.0/library/exceptions.html#exceptions.ImportWarning) | Базовая категория для предупреждений, возникающих в процессе импорта модуля (игнорируется по умолчанию). |35| [`UnicodeWarning`](https://python-all.ru/3.0/library/exceptions.html#exceptions.UnicodeWarning) | Базовая категория для предупреждений, связанных с Юникодом. |36| [`BytesWarning`](https://python-all.ru/3.0/library/exceptions.html#exceptions.BytesWarning) | Базовая категория для предупреждений, связанных с [`bytes`](https://python-all.ru/3.0/library/functions.html#bytes) и `buffer`. |3738Хотя технически это встроенные исключения, они документируются здесь, поскольку концептуально относятся к механизму предупреждений.3940Пользовательский код может определять дополнительные категории предупреждений, наследуя одну из стандартных категорий. Категория предупреждения всегда должна быть подклассом класса [`Warning`](https://python-all.ru/3.0/library/exceptions.html#exceptions.Warning).4142## Фильтр предупреждений4344Фильтр предупреждений управляет тем, игнорируются ли предупреждения, выводятся на экран или превращаются в ошибки (вызывают исключение).4546Концептуально фильтр предупреждений поддерживает упорядоченный список спецификаций фильтра; каждое конкретное предупреждение последовательно сопоставляется с каждой спецификацией фильтра в списке, пока не будет найдено совпадение; совпадение определяет дальнейшие действия. Каждая запись представляет собой кортеж вида (*action*, *message*, *category*, *module*, *lineno*), где:4748- *Действие* – одна из следующих строк:4950  | Значение | Действие |51  | --- | --- |52  | `"error"` | превращать подходящие предупреждения в исключения |53  | `"ignore"` | никогда не выводить подходящие предупреждения |54  | `"always"` | всегда выводить подходящие предупреждения |55  | `"default"` | выводит первое появление соответствующих предупреждений для каждого места, где было выдано предупреждение |56  | `"module"` | выводит первое появление соответствующих предупреждений для каждого модуля, где было выдано предупреждение |57  | `"once"` | выводить только первое вхождение подходящих предупреждений, независимо от местоположения |58- *message* – строка, содержащая регулярное выражение, которому должно соответствовать сообщение предупреждения (сопоставление компилируется так, чтобы всегда быть без учёта регистра).59- *category* – класс (подкласс [`Warning`](https://python-all.ru/3.0/library/exceptions.html#exceptions.Warning)), подклассом которого должна быть категория предупреждения, чтобы произошло совпадение.60- *module* – строка, содержащая регулярное выражение, которому должно соответствовать имя модуля (сопоставление компилируется с учётом регистра).61- *lineno* – целое число, которому должен соответствовать номер строки, в которой возникло предупреждение, или `0` для соответствия любым номерам строк.6263Поскольку класс [`Warning`](https://python-all.ru/3.0/library/exceptions.html#exceptions.Warning) наследуется от встроенного класса [`исключения`](https://python-all.ru/3.0/library/exceptions.html#exceptions.Exception), чтобы превратить предупреждение в ошибку, достаточно возбудить `category(message)`.6465Фильтр предупреждений инициализируется параметрами [*-W*](https://python-all.ru/3.0/using/cmdline.html#cmdoption-W), переданными в командную строку интерпретатора Python. Интерпретатор сохраняет аргументы всех параметров [*-W*](https://python-all.ru/3.0/using/cmdline.html#cmdoption-W) без интерпретации в `sys.warnoptions`; модуль `warnings` разбирает их при первом импорте (недопустимые параметры игнорируются после вывода сообщения в `sys.stderr`).6667Предупреждения, которые по умолчанию игнорируются, можно включить, передав *-Wd* интерпретатору. Это включает обработку по умолчанию для всех предупреждений, включая те, которые обычно игнорируются. Это особенно полезно для включения ImportWarning при отладке проблем с импортом разрабатываемого пакета. ImportWarning также можно явно включить в коде Python с помощью:6869```python70warnings.simplefilter('default', ImportWarning)71```7273## Временное подавление предупреждений7475Если используется код, который, как известно, вызовет предупреждение (например, устаревшая функция), но выводить предупреждение не требуется, то его можно подавить с помощью менеджера контекста [`catch_warnings`](https://python-all.ru/3.0/library/warnings.html#warnings.catch_warnings):7677```python78import warnings7980def fxn():81    warnings.warn("deprecated", DeprecationWarning)8283with warnings.catch_warnings():84    warnings.simplefilter("ignore")85    fxn()86```8788Внутри контекстного менеджера все предупреждения просто игнорируются. Это позволяет использовать заведомо устаревший код, не видя предупреждения, при этом не подавляя предупреждения для другого кода, который может не знать об использовании устаревшего кода.8990## Тестирование предупреждений9192Для тестирования предупреждений, вызываемых кодом, используйте менеджер контекста [`catch_warnings`](https://python-all.ru/3.0/library/warnings.html#warnings.catch_warnings). С его помощью можно временно изменить фильтр предупреждений для упрощения тестирования. Например, сделайте следующее, чтобы перехватить все возникшие предупреждения и проверить их:9394```python95import warnings9697def fxn():98    warnings.warn("deprecated", DeprecationWarning)99100with warnings.catch_warnings(record=True) as w:101    # Привести к тому, что все предупреждения всегда будут срабатывать.102    warnings.simplefilter("always")103    # Вызвать предупреждение.104    fxn()105    # Проверить некоторые вещи106    assert len(w) == 1107    assert isinstance(w[-1].category, DeprecationWarning)108    assert "deprecated" in str(w[-1].message)109```110111Можно также сделать все предупреждения исключениями, используя `error` вместо `always`. Следует учитывать, что если предупреждение уже было вызвано из-за правила `once`/`default`, то, независимо от установленных фильтров, предупреждение не будет показано снова, пока не будет очищен реестр предупреждений, связанный с этим предупреждением.112113Когда менеджер контекста завершает работу, фильтр предупреждений восстанавливается в состояние, которое было при входе в контекст. Это предотвращает изменение фильтра предупреждений тестами неожиданным образом между тестами и, как следствие, получение неопределённых результатов. Функция [`showwarning()`](https://python-all.ru/3.0/library/warnings.html#warnings.showwarning) в модуле также восстанавливается до своего исходного значения.114115При тестировании нескольких операций, вызывающих один и тот же тип предупреждения, важно тестировать их так, чтобы подтвердить, что каждая операция вызывает новое предупреждение (например, настроить предупреждения как исключения и проверить, что операции вызывают исключения, проверить, что длина списка предупреждений увеличивается после каждой операции, или удалять предыдущие записи из списка предупреждений перед каждой новой операцией).116117## Доступные функции118119#### `[warnings.warn]warnings.warn(message[, category[, stacklevel]])`120121Выдаёт предупреждение, либо игнорирует его, либо возбуждает исключение. Аргумент *category*, если задан, должен быть классом категории предупреждения (см. выше); по умолчанию он равен [`UserWarning`](https://python-all.ru/3.0/library/exceptions.html#exceptions.UserWarning). Альтернативно, *message* может быть экземпляром [`Warning`](https://python-all.ru/3.0/library/exceptions.html#exceptions.Warning), и в этом случае *category* будет проигнорирован, а будет использовано `message.__class__`. В этом случае текст сообщения будет равен `str(message)`. Эта функция возбуждает исключение, если конкретное выданное предупреждение превращается в ошибку фильтром предупреждений (см. выше). Аргумент *stacklevel* может использоваться функциями-обёртками, написанными на Python, как показано ниже:122123```python124def deprecation(message):125    warnings.warn(message, DeprecationWarning, stacklevel=2)126```127128Это заставляет предупреждение ссылаться на вызывающий код функции `deprecation()`, а не на источник самой `deprecation()` (поскольку последнее сделало бы предупреждение бессмысленным).129130#### `[warnings.warn_explicit]warnings.warn_explicit(message, category, filename, lineno[, module[, registry[, module_globals]]])`131132Это низкоуровневый интерфейс к функциональности [`warn()`](https://python-all.ru/3.0/library/warnings.html#warnings.warn), в который явно передаются сообщение, категория, имя файла и номер строки, а также опционально имя модуля и реестр (который должен быть словарём `__warningregistry__` модуля). Имя модуля по умолчанию равно имени файла без расширения `.py`; если реестр не передан, предупреждение никогда не подавляется. *message* должна быть строкой, а *category* – подклассом [`Warning`](https://python-all.ru/3.0/library/exceptions.html#exceptions.Warning), либо *message* может быть экземпляром [`Warning`](https://python-all.ru/3.0/library/exceptions.html#exceptions.Warning), и в этом случае *category* будет проигнорирован.133134*module\_globals*, если указан, должно быть глобальным пространством имён, используемым кодом, для которого выдаётся предупреждение. (Этот аргумент используется для поддержки отображения исходного кода для модулей, найденных в zip-файлах или других источниках импорта, не основанных на файловой системе).135136#### `[warnings.showwarning]warnings.showwarning(message, category, filename, lineno[, file[, line]])`137138Записывает предупреждение в файл. Реализация по умолчанию вызывает139140`formatwarning(message, category, filename, lineno, line)`141142и записывает полученную строку в143144*file*145146, который по умолчанию равен147148`sys.stderr`149150. Можно заменить эту функцию альтернативной реализацией, присвоив новое значение151152`warnings.showwarning`153154.155156*line*157158– строка исходного кода, которая будет включена в сообщение предупреждения; если159160*line*161162не указан,163164[`showwarning()`](https://python-all.ru/3.0/library/warnings.html#warnings.showwarning)165166попытается прочитать строку, указанную в167168*filename*169170и171172*lineno*173174.175176#### `[warnings.formatwarning]warnings.formatwarning(message, category, filename, lineno[, line])`177178Форматирует предупреждение стандартным способом. Возвращает строку, которая может содержать встроенные переводы строк и заканчивается переводом строки.179180*line*181182– строка исходного кода, которая будет включена в сообщение предупреждения; если183184*line*185186не указан,187188[`formatwarning()`](https://python-all.ru/3.0/library/warnings.html#warnings.formatwarning)189190попытается прочитать строку, заданную191192*filename*193194и195196*lineno*197198.199200#### `[warnings.filterwarnings]warnings.filterwarnings(action[, message[, category[, module[, lineno[, append]]]]])`201202Вставляет запись в список фильтров предупреждений. По умолчанию запись вставляется в начало; если203204*append*205206равен true, она вставляется в конец. Эта функция проверяет типы аргументов, компилирует регулярные выражения для сообщения и модуля и вставляет их в виде кортежа в список фильтров предупреждений. Записи, расположенные ближе к началу списка, переопределяют записи, расположенные позже, если обе соответствуют конкретному предупреждению. Опущенные аргументы по умолчанию принимают значение, которое соответствует всему.207208#### `[warnings.simplefilter]warnings.simplefilter(action[, category[, lineno[, append]]])`209210Вставляет простую запись в список фильтров предупреждений. Смысл параметров функции такой же, как у211212[`filterwarnings()`](https://python-all.ru/3.0/library/warnings.html#warnings.filterwarnings)213214, но регулярные выражения не требуются, так как вставленный фильтр всегда соответствует любому сообщению в любом модуле при условии совпадения категории и номера строки.215216#### `[warnings.resetwarnings]warnings.resetwarnings()`217218Сбрасывает фильтр предупреждений. Отменяет действие всех предыдущих вызовов219220[`filterwarnings()`](https://python-all.ru/3.0/library/warnings.html#warnings.filterwarnings)221222, включая опции командной строки223224[*-W*](https://python-all.ru/3.0/using/cmdline.html#cmdoption-W)225226и вызовы227228[`simplefilter()`](https://python-all.ru/3.0/library/warnings.html#warnings.simplefilter)229230.231232## Доступные контекстные менеджеры233234#### `[warnings.catch_warnings]class warnings.catch_warnings([*, record=False, module=None])`235236Менеджер контекста, который копирует и при выходе восстанавливает фильтр предупреждений и функцию [`showwarning()`](https://python-all.ru/3.0/library/warnings.html#warnings.showwarning). Если аргумент *record* равен [`False`](https://python-all.ru/3.0/library/constants.html#False) (по умолчанию), менеджер контекста возвращает [`None`](https://python-all.ru/3.0/library/constants.html#None) при входе. Если *record* равен [`True`](https://python-all.ru/3.0/library/constants.html#True), возвращается список, который постепенно заполняется объектами, наблюдаемыми пользовательской функцией [`showwarning()`](https://python-all.ru/3.0/library/warnings.html#warnings.showwarning) (которая также подавляет вывод в `sys.stdout`). Каждый объект в списке имеет атрибуты с теми же именами, что и аргументы [`showwarning()`](https://python-all.ru/3.0/library/warnings.html#warnings.showwarning).237238Аргумент *module* принимает модуль, который будет использоваться вместо модуля, возвращаемого при импорте `warnings`, чей фильтр будет защищён. Этот аргумент существует в основном для тестирования самого модуля `warnings`.239