warnings.warn () против logging.warning ()

82

В чем разница между warnings.warn()и logging.warn()с точки зрения того, что они делают и как они должны быть использованы?

Хекевинтран
источник
8
не могли бы вы изменить здесь принятый ответ?
Антти Хаапала

Ответы:

-5

Один вызывает исключение, которое может быть перехвачено или проигнорировано по желанию, а другой, при необходимости, добавляет запись в журнал на основе текущего уровня ведения журнала. Один должен использоваться, когда один предупреждает о различных вещах в коде, а другой должен использоваться при регистрации.

Игнасио Васкес-Абрамс
источник
23
Насколько я понимаю, принятый ответ неверен. Ни предупреждения, ни логгирование не вызывают исключения. Но распечатайте сообщения. Однако они имеют другую систематичность (однако можно интегрировать предупреждения в журнал через logging.captureWarnings()). Предупреждающие сообщения по умолчанию отображаются только один раз, как объяснил @cxrodgers, чтобы указать пользователю изменить свой код. Однако, ведя журнал на другом и документируя все предупреждения, можно настроить отображение подробностей. Предупреждения об исключениях могут выводиться с помощью параметра -W error.
DerWeh 02
К сожалению, этот ответ не очень полезен. "поднимать ..." и "надо ..."? Что есть что? warningsили logging?
Питер Лиллевольд,
86

Я согласен с другим ответом - loggingдля регистрации иwarning для предупреждения, но я хотел бы добавить более подробную информацию.

Вот HOWTO в стиле учебника, в котором вы узнаете, как использовать loggingмодуль. https://docs.python.org/3/howto/logging.html

Он прямо отвечает на ваш вопрос:

warnings.warn () в коде библиотеки, если проблему можно избежать и клиентское приложение следует изменить, чтобы исключить предупреждение

logging.warning (), если клиентское приложение ничего не может сделать с ситуацией, но событие все же следует отметить.

cxrodgers
источник
60

logging.warningпросто регистрирует что-то на WARNINGуровне, точно так же, как logging.infoведет журнал на INFOуровне и logging.errorведет журнал на ERRORуровне. Особого поведения не имеет.

warnings.warnиспускает a Warning, который может быть напечатан stderr, полностью проигнорирован или брошен как обычно Exception(что может привести к сбою вашего приложения) в зависимости от точного Warningсозданного подкласса и того, как вы настроили свой фильтр предупреждений . По умолчанию предупреждения выводятся stderrили игнорируются.

Предупреждения, выдаваемые службой warnings.warn, часто полезно знать, но их легко пропустить (особенно если вы запускаете программу Python в фоновом режиме, а не в захват stderr). По этой причине может быть полезно зарегистрировать их.

Python предоставляет встроенную интеграцию между loggingмодулем и warningsмодулем, чтобы вы могли это сделать; просто вызовите logging.captureWarnings(True)в начале своего скрипта, и все предупреждения, выдаваемые warningsмодулем, будут автоматически регистрироваться на уровне WARNING.

Марк Эмери
источник
27

Помимо канонического объяснения в официальной документации

warnings.warn () в коде библиотеки, если проблему можно избежать и клиентское приложение следует изменить, чтобы исключить предупреждение

logging.warning (), если клиентское приложение ничего не может сделать с ситуацией, но событие все же следует отметить.

Также стоит отметить, что по умолчанию warnings.warn("same message")будет отображаться только один раз. Это очень заметная разница. Цитата из официального документа

Повторения конкретного предупреждения для одного и того же источника обычно подавляются.

>>> import warnings
>>> warnings.warn("foo")
__main__:1: UserWarning: foo
>>> warnings.warn("foo")
>>> warnings.warn("foo")
>>>
>>> import logging
>>> logging.warn("bar")
WARNING:root:bar
>>> logging.warn("bar")
WARNING:root:bar
>>> logging.warn("bar")
WARNING:root:bar
>>>
>>>
>>> warnings.warn("fur")
__main__:1: UserWarning: fur
>>> warnings.warn("fur")
>>> warnings.warn("fur")
>>>
RayLuo
источник
1
Обратите внимание, что «показывать только один раз» - это предполагаемое поведение по умолчанию, но фильтры предупреждений могут это изменить.
gerrit