在Django,我到处都有记录器,目前有硬编码名称。
对于模块级日志记录(即在视图函数模块中),我有这样做的冲动。
log = logging.getLogger(__name__)
对于类级别的日志记录(即,在类__init__
方法中),我有这样做的冲动。
self.log = logging.getLogger("%s.%s" % (
self.__module__, self.__class__.__name__))
在我处理好几十次getLogger("hard.coded.name")
之前,我正在寻找第二意见。
这会有用吗?还有其他人用同样缺乏想象力的方式命名他们的记录器吗?
此外,我应该分解并为此日志定义编写类装饰器吗?
答案 0 :(得分:67)
我通常不使用或不需要类级记录器,但我最多只保留几个类。一个简单的:
import logging
LOG = logging.getLogger(__name__)
在模块的顶部和随后的:
LOG.info('Spam and eggs are tasty!')
从文件中的任何位置通常都会让我到达我想要的位置。这样可以避免在整个地方都需要self.log
,这往往会让我从每个班级的角度来看都会让我感到困扰,并使我更接近于符合79个字符行的5个字符。
你总是可以使用伪类装饰器:
>>> 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
答案 1 :(得分:3)
对于类级别日志记录,作为伪类装饰器的替代,您可以使用元类在创建类时为您创建记录器...
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 :(得分:2)
看起来它会起作用,但self
不会有__module__
属性;它的班级会。类级记录器调用应如下所示:
self.log = logging.getLogger( "%s.%s" % ( self.__class__.__module__, self.__class__.__name__ ) )