很好的一天。我试图解决登录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')

07-24 09:45
查看更多