Python – Избегать прохождения ссылки на регистратор между функциями?

У меня есть простой скрипт Python, который использует встроенный logging .

Я настраиваю ведение журнала внутри функции. Основная структура будет примерно такой:

 #!/usr/bin/env python import logging import ... def configure_logging(): logger = logging.getLogger("my logger") logger.setLevel(logging.DEBUG) # Format for our loglines formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") # Setup console logging ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) ch.setFormatter(formatter) logger.addHandler(ch) # Setup file logging as well fh = logging.FileHandler(LOG_FILENAME) fh.setLevel(logging.DEBUG) fh.setFormatter(formatter) logger.addHandler(fh) return logger def count_parrots(): ... logger.debug?? if __name__ == '__main__': logger = configure_logging() logger.debug("I'm a log file") parrots = count_parrots() 

Я могу вызвать логгер изнутри __main__ . Однако как я могу вызвать регистратор из функции count_parrots ()? Какой самый pythonic способ обработки конфигурации регистратора, как это?

5 Solutions collect form web for “Python – Избегать прохождения ссылки на регистратор между функциями?”

Вы можете либо использовать корневой (по умолчанию) регистратор, и, таким образом, уровень модуля функции logging.debug , … или получить ваш регистратор в функции, используя его. Действительно, функция getLogger – это фабрично-подобная функция с реестром (однопользовательская), т. getLogger Она всегда возвращает тот же экземпляр для данного имени журнала. Таким образом, вы можете получить свой регистратор в count_parrots, просто используя

 logger = logging.getLogger("my logger") 

в начале. Тем не менее, соглашение заключается в использовании точечного иерархического имени для вашего регистратора. См. http://docs.python.org/library/logging.html#logging.getLogger

РЕДАКТИРОВАТЬ:

Вы можете использовать декоратор, чтобы добавить поведение журнала в свои индивидуальные функции, например:

 def debug(loggername): logger = logging.getLogger(loggername) def log_(enter_message, exit_message=None): def wrapper(f): def wrapped(*args, **kargs): logger.debug(enter_message) r = f(*args, **kargs) if exit_message: logger.debug(exit_message) return r return wrapped return wrapper return log_ my_debug = debug('my.logger') @my_debug('enter foo', 'exit foo') def foo(a, b): return a+b 

вы можете «жестко закодировать» имя регистратора и удалить закрытие верхнего уровня и my_debug.

Вы можете просто сделать:

 logger = logging.getLogger("my logger") 

в вашем count_parrots() . Когда вы передаете имя, которое использовалось ранее (то есть «мой регистратор»), модуль регистрации вернет тот же экземпляр, который был создан в соответствии с этим именем.

Обновление: из учебника по протоколированию (см.

getLogger () возвращает ссылку на экземпляр журнала с указанным именем, если он указан, или root, если нет. Имена представляют собой иерархические структуры, разделенные периодом. Несколько вызовов в getLogger () с тем же именем возвращают ссылку на тот же объект журнала.

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

Это кратко обсуждается во вступлении к учебному руководству по продвижению в документации: http://docs.python.org/howto/logging.html#advanced-logging-tutorial

Вы можете передавать экземпляры журнала в качестве параметров, но это обычно бывает редко.

Я запутался в том, как глобальные переменные работают в Python. Внутри функции вам нужно только объявить global logger если вы делаете что-то вроде logger = logging.getLogger("my logger") и надеетесь изменить глобальный logger .

Поэтому, чтобы изменить ваш пример, вы можете создать глобальный объект журнала в начале файла. Если ваш модуль может быть импортирован другим, вы должны добавить NullHandler чтобы, если импортер библиотеки не хочет, чтобы регистрация была включена, у них нет проблем с вашей lib ( ref ).

 #!/usr/bin/env python import logging import ... logger = logging.getLogger("my logger").addHandler(logging.NullHandler()) def configure_logging(): logger.setLevel(logging.DEBUG) # Format for our loglines formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") # Setup console logging ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) ch.setFormatter(formatter) logger.addHandler(ch) # Setup file logging as well fh = logging.FileHandler(LOG_FILENAME) fh.setLevel(logging.DEBUG) fh.setFormatter(formatter) logger.addHandler(fh) def count_parrots(): ... logger.debug('counting parrots') ... return parrots if __name__ == '__main__': configure_logging() logger.debug("I'm a log file") parrots = count_parrots() 

Вы можете предоставить logger качестве аргумента для count_parrots() Или, что бы я сделал, создайте попугаев классов и используем logger как один из его методов.

 
Interesting Posts for Van-Lav

Как заставить Visual Express 2010 найти файл заголовка python.h?

Хороший способ превратить длинные строки в новую строку в Python?

Как сделать строку unicode с python3

Изменение размера изображения полярной координаты

Как я могу убить SimpleHTTPServer из сценария Python?

Распаковка, расширенная распаковка и вложенная расширенная распаковка

Профилирование Python. Каковы столбцы в выводе runnakerun?

Будет ли scikit-learn использовать GPU?

Хранение словарей Python

Spark + Python – Процесс Java-шлюза вышел, прежде чем отправить драйверу номер своего порта?

Вставить Графический график на веб-страницу с помощью Бутылки

Apache Spark: работа прерывается из-за срыва этапа: «TID x не удалось по неизвестным причинам»

Как разрешить пользователям входить в защищенный флажок-rest-api в Angularjs, используя HTTP-аутентификацию?

Разделить строку unicode на 300 байтовых фрагментов без уничтожения символов

Преобразовать float в строку с нулевым десятичным значком afer point в Python

Python - лучший язык программирования в мире.