很好的一天。我试图解决登录Python的问题。我使用的是Python3.5.1。我有一个应用程序,它使用一个类,从其他模块导入。我无法为它启用日志记录。这是一个简单的表示:
# test.py
import logging
from test_class import TestClass
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
logger.addHandler(logging.FileHandler('test_log.log', mode='w'))
if __name__ == '__main__':
logger.info('Importing class')
t = TestClass()
t.make_call()
t.make_another_call()
logger.info('End')
# test_class.py
import logging
class TestClass(object):
def __init__(self):
self.logger = logging.getLogger('test_class.TestClass')
def make_call(self):
self.logger.info('Make a call')
def make_another_call(self):
self.logger.info('Make another call')
如您所见,logger必须为行(两个来自主模块,两个来自类)写入文件。但当我打开日志文件时,我看到:
# test_log.log
Importing class
End
所以,来自类的两个记录器调用没有效果。知道吗,为什么不行?提前谢谢你。
最佳答案
从the docs:
多次调用具有相同名称的getLogger()将始终返回对同一个Logger对象的引用。
该名称可能是一个以句点分隔的层次结构值,例如foo.bar.baz(尽管它也可以是纯foo)。在层次结构列表中较低的记录器是列表中较高的记录器的子级。例如,给定一个名为foo的记录器,名为foo.bar、foo.bar.baz和foo.bam的记录器都是foo的后代。logger name层次结构类似于Python包层次结构,如果使用建议的构造logging.getLogger(__name__)
按模块组织logger,则与之相同。这是因为在模块中,__name__
是Python包名称空间中模块的名称。
在代码中调用getLogger
的方式是,用test.py
完成对__main__
的调用,用test_class.py
完成对test_class
的调用,因此后者不是前者的后代。
相反,如果在设置处理程序时,对调用getLogger()
得到的对象执行此操作,而不带参数,则将在根日志对象上设置处理程序,并且对getLogger()
的所有其他调用都将在层次结构的下一层,并将使用指定的处理程序。
如果要继续在主模块中为日志语句设置名称,只需在设置处理程序后再次调用getLogger
。
例如:
# Call getLogger with no args to set up the handler
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
logger.addHandler(logging.FileHandler('test_log.log', mode='w'))
if __name__ == '__main__':
# call getLogger again with a name to tag subsequent log statements
logger = logging.getLogger(__name__)
logger.info('Importing class')
t = TestClass()
t.make_call()
t.make_another_call()
logger.info('End')