Повторяющиеся сообщения от регистратора классов - PullRequest
3 голосов
/ 21 апреля 2019

Мой класс создает регистратор, названный в честь класса в init (). Теперь, когда я регистрирую сообщение, я получаю одну копию сообщения для каждого экземпляра класса, который был создан до сих пор. Как мне избежать этого дублирования?

Я также обеспокоен тем, что это может быть просто симптомом более глубокой проблемы - является ли это расточительным подходом к управлению памятью в приложении, которое может создавать несколько сотен классов одновременно? Есть ли более разумный способ обработки журналов в нескольких классах?

Хотя приведенный ниже код является упрощенным повторением проблемы, реальный код является очень модульным, и каждый класс может использоваться по-разному в различных приложениях. Каждый класс может использоваться как отдельный класс, вызываемый определенным с помощью метода main (), или он может вызываться из другого класса или из одного из трех или четырех основных приложений. Подход к ведению журнала должен учитывать эту модульность.

import logging

class person:
    def __init__(self,name):
        self.name = name
        logger = logging.getLogger('person logger')
        logger.setLevel(logging.DEBUG)
        ch = logging.StreamHandler()
        formatter = logging.Formatter('%(name)s - %(message)s')
        ch.setFormatter(formatter)
        logger.addHandler(ch)

        logger.info(f'{self.name} exists')


if __name__ == '__main__':

    for name in ["Alice", "Bob", "Carlos"] :
        a = person(name)

Ожидаемые результаты:

person logger - Alice exists
person logger - Bob exists
person logger - Carlos exists

Фактические результаты:

person logger - Alice exists
person logger - Bob exists
person logger - Bob exists
person logger - Carlos exists
person logger - Carlos exists
person logger - Carlos exists

1 Ответ

4 голосов
/ 21 апреля 2019

Используйте if logger.handlers, чтобы проверить, были ли уже обработчики. Или вы добавляете обработчик каждый раз, когда создаете объект person.

В основном:

import logging

class person:
    def __init__(self,name):
        self.name = name
        logger = logging.getLogger('person logger')
        logger.setLevel(logging.DEBUG)
        if not logger.handlers:
            ch = logging.StreamHandler()
            formatter = logging.Formatter('%(name)s - %(message)s')
            ch.setFormatter(formatter)
            logger.addHandler(ch)

        logger.info(f'{self.name} exists')


if __name__ == '__main__':

    for name in ["Alice", "Bob", "Carlos"] :
        a = person(name)

Кроме того, в основном мы создаем не регистратор для класса, а для модуля.

Для огромного проекта создайте модуль log_helper, который может содержать функцию инициализации:

def getLogger(name):
    logger = logging.getLogger(name)
    # do some initialization...
    # like adding handlers
    return logger

И получите регистратор в верхней части каждого модуля:

# person.py  Module person

import log_helper

logger = log_helper.getLogger("person") # or whatever you want

# just use this logger...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...