Python。为 class 实例启用日志记录,从单独的模块导入

Python. Enable logging for a class instance, imported from separated module

美好的一天。我正在尝试解决登录 Python 的问题。我正在使用 Python 3.5.1。我有一个应用程序,它使用从其他模块导入的 class。我无法为其启用日志记录。这是一个简单的表示:

# 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')

如您所见,记录器必须将行写入文件(两个来自主模块,两个来自 class。但是当我打开日志文件时,我看到:

# test_log.log
Importing class
End

因此,来自 class 的两次记录器调用没有效果。任何想法,为什么它不起作用?提前谢谢你。

来自 the docs:

Multiple calls to getLogger() with the same name will always return a reference to the same Logger object.

The name is potentially a period-separated hierarchical value, like foo.bar.baz (though it could also be just plain foo, for example). Loggers that are further down in the hierarchical list are children of loggers higher up in the list. For example, given a logger with a name of foo, loggers with names of foo.bar, foo.bar.baz, and foo.bam are all descendants of foo. The logger name hierarchy is analogous to the Python package hierarchy, and identical to it if you organise your loggers on a per-module basis using the recommended construction logging.getLogger(__name__). That’s because in a module, __name__ is the module’s name in the Python package namespace.

您在代码中调用 getLogger 的方式,test.py 中的调用是通过 __main__ 完成的,而 test_class.py 中的调用是通过 [=17= 完成的], 所以后者不是前者的后代

相反,如果在您设置处理程序时,您在通过调用 getLogger() 获得的对象上执行此操作而没有参数,您将在根日志记录对象和所有其他调用上设置处理程序to 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')