Именование регистраторов Python - PullRequest
47 голосов
/ 30 декабря 2008

В Django у меня везде есть регистраторы, в настоящее время с жестко закодированными именами.

Для ведения журнала на уровне модуля (т. Е. В модуле функций просмотра) у меня есть желание сделать это.

log = logging.getLogger(__name__)

Для ведения журнала на уровне класса (т. Е. В методе класса __init__) у меня есть желание сделать это.

self.log = logging.getLogger("%s.%s" % (
    self.__module__, self.__class__.__name__))

Я ищу второе мнение перед тем, как заняться несколькими десятками случаев getLogger("hard.coded.name").

Будет ли это работать? Кто-нибудь еще называет свои логгеры такими же невообразимыми способами?

Далее, я должен сломаться и написать декоратор класса для этого определения журнала?

Ответы [ 3 ]

67 голосов
/ 31 декабря 2008

Я обычно не использую или не нахожу необходимость в регистраторах уровня класса, но я держу свои модули максимум в нескольких классах. Простое:

import logging
LOG = logging.getLogger(__name__)

В верхней части модуля и далее:

LOG.info('Spam and eggs are tasty!')

из любого места в файле обычно приводит меня туда, где я хочу быть. Это исключает необходимость повсеместного использования self.log, что, как правило, беспокоит меня с точки зрения «ставь все в каждый класс» и приближает меня на 5 символов к 79 подходящим символам.

Вы всегда можете использовать псевдокласс-декоратор:

>>> import logging
>>> class Foo(object):
...     def __init__(self):
...             self.log.info('Meh')
... 
>>> def logged_class(cls):
...     cls.log = logging.getLogger('{0}.{1}'.format(__name__, cls.__name__))
... 
>>> logged_class(Foo)
>>> logging.basicConfig(level=logging.DEBUG)
>>> f = Foo()
INFO:__main__.Foo:Meh
3 голосов
/ 27 октября 2009

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

import logging

class Foo(object):
    class __metaclass__(type):
        def __init__(cls, name, bases, attrs):
            type.__init__(name, bases, attrs)
            cls.log = logging.getLogger('%s.%s' % (attrs['__module__'], name))
    def __init__(self):
        self.log.info('here I am, a %s!' % type(self).__name__)

if __name__ == '__main__':
    logging.basicConfig(level=logging.DEBUG)
    foo = Foo()
2 голосов
/ 30 декабря 2008

Похоже, что это будет работать, за исключением того, что self не будет иметь атрибута __module__; его класс будет. Вызов регистратора уровня класса должен выглядеть следующим образом:

self.log = logging.getLogger( "%s.%s" % ( self.__class__.__module__, self.__class__.__name__ ) )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...