2008-12-30 16 views
45

En Django, tengo registradores por todas partes, actualmente con nombres codificados.Nombramiento de registradores de Python

Para el registro a nivel de módulo (es decir, en un módulo de funciones de visualización) Tengo la necesidad de hacerlo.

log = logging.getLogger(__name__) 

Para el registro de nivel de clase (es decir, en un método de la clase __init__) tengo la necesidad de hacer esto.

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

Busco una segunda opinión antes de abordo varias decenas de apariciones de getLogger("hard.coded.name").

¿Funcionará? ¿Alguien más nombra a sus registradores con las mismas formas sin imaginación?

Además, ¿debo analizar y escribir un decorador de clase para esta definición de registro?

+0

Tengo curiosidad: ¿por qué querrías loggin a nivel de clase? – glarrain

Respuesta

65

que normalmente no uso o encontrar una necesidad de registradores de nivel de clase, pero mantener los módulos en algunas clases como máximo. Una simple:

import logging 
LOG = logging.getLogger(__name__) 

En la parte superior del módulo y posterior:

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

desde cualquier parte del archivo normalmente me lleva a donde quiero estar. Esto evita la necesidad de self.log en todas partes, lo que me molesta desde una perspectiva de ponerlo en todas las clases y me hace 5 caracteres más cerca de las 79 líneas de caracteres que caben.

Siempre se puede utilizar un pseudo-clase-decorador:

>>> 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 
+7

Enfoque interesante ...Creo que pasé mucho tiempo con Java. El registro a nivel de módulo puede ser justo lo que ordenó el médico. –

+7

Hay un problema con el uso de '__name__': cuando el módulo se importa en alguna parte usando una importación relativa, sus mensajes irán al registro usando ese' __name__' más corto. Esto no es un problema siempre que evite estas importaciones relativas, que de todos modos son malas (como se indica en las preguntas frecuentes de Python) – c089

2

Parece que funcionará, excepto que self no tendrá un atributo __module__; su clase lo hará. La llamada registrador de nivel de clase debe ser similar:

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

¿Estás seguro de que uno mismo no tendrá un atributo __module__? Lo intenté y parecía tener uno. – Kiv

+0

self tiene un atributo __module__. –

+0

extraño ... >>> fecha y hora de la fecha de importación >>> d = date.today() >>> d .__ module__ Rastreo (llamada más reciente pasado): Archivo "", línea 1, en AttributeError: 'datetime.date' objeto no tiene atributo '__module__' >>> d .__ clase __.__ module__ 'fecha y hora' >>> –

3

Para el registro de nivel de clase, como una alternativa a un decorador pseudo-clase, se puede utilizar una metaclase para que el registrador para que en clase tiempo de creación ...

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() 
+0

Tuve que cambiar 'tipo .__ init __ (...)' a 'objeto .__ init __ (.. .) ', o habrá un error en python 2.7:' descriptor '__init__' requiere un objeto 'tipo' pero recibió un 'str''. Pero no puedo hacer que este método funcione en python 3.x. –

+0

Lo descubrí. Para que este método también funcione para python 3.x, necesito escribir la metaclase por separado, y usar hack como 'logging_metaclass_hack = logging_metaclass (" logging_metaclass_hack ", (object,), {})' y heredar a Foo. –

Cuestiones relacionadas