Ответ 1
Вопрос был поднят здесь.
Наблюдение заключается в следующем: в обычном питоне или в консоли IPython обработчик корневого регистратора не установлен до тех пор, пока сам корневой журнал не будет использоваться для сообщения журнала:
In [1]: import logging
In [2]: logging.getLogger().handlers
Out[2]: []
In [3]: logging.warn('Something happened!')
WARNING:root:Something happened!
In [4]: logging.getLogger().handlers
Out[4]: [<logging.StreamHandler at 0x42acef0>]
Однако в ноутбуке IPython установлен корневой регистратор stderr по умолчанию:
In [1]: import logging
In [2]: logging.getLogger().handlers
Out[2]: [<logging.StreamHandler at 0x35eedd8>]
Может быть, мне что-то не хватает, но я думаю, что в записной книжке не должно быть установлено автоматически, по нескольким причинам:
- Это сделает конфигурацию протоколирования по умолчанию совместимой между стандартным питоном, консолью IPython и ноутбуком IPython.
- Как только пользователь записывает сообщение журнала с корневым журналом, обработчик устанавливается автоматически, поэтому сообщения журнала нелегко пропустить.
- В текущем поведении библиотека, которая настраивает дочерний регистратор, и обработчик для этого регистратора, может легко спамить ноутбук сообщениями отладки, которые должны находиться только в файле журнала (или в другом месте). Например, у астрологии, похоже, есть такая проблема, и я сталкиваюсь с той же проблемой с моей собственной библиотекой. Проблема в том, что для такой библиотеки нет "чистого" способа обойти это. Библиотека может удалить обработчик корневого регистратора при импорте, который является hack-y. Он мог бы установить свой собственный logger
propagate
атрибутFalse
, чтобы сообщения журнала не распространялись на корневой журнал, но это не только отключает вывод отладки из входа в ноутбук, но и более серьезные сообщения. Кроме того, он запрещает пользователям фактически захватывать все выходные данные журнала, если они хотят.
Альтернативой может быть добавление опции конфигурации, которая определяет уровень журнала для автоматически добавленного обработчика потока, так что становится возможным игнорировать менее серьезные сообщения, появляющиеся в ноутбуке автоматически. Но это все равно по-разному повлияет на поведение между консолью IPython и ноутбуком IPython.
Единственный недостаток, который я вижу в том, что нет набора обработчиков по умолчанию, заключается в том, что некоторые используемые библиотеки/ноутбуки могут полагаться на это поведение и активно работать вокруг него, например, отключив их собственные обработчики, если они обнаружат, что они запущены в ноутбуке ipython. Такие случаи, вероятно, нарушатся с таким изменением.
Таким образом, установка logger.propagate
to False
или использование reload(logging)
предотвратит дублирование вывода, но в зависимости от этого будут иметь побочные эффекты.
Обратите внимание, что reload
недоступен в более новой версии python (3.4, возможно, раньше). Начиная с 3.1 и далее см. importlib.reload