假设我有以下a.py
,它调用b.py
b.py
import logging
logging.info('11111 in b')
def do():
logging.info('2222222 in b')
a.py
import logging
import sys
import b
logging.basicConfig(stream=sys.stdout, level=logging.INFO)
logging.info('11111111 in a')
b.do()
当我执行a.py
时,没有任何东西被记录到stdout
,但当我从b.py
注释掉logging.info('11111 in b')
时,如下所示:
b.p
y
import logging
# logging.info('11111 in b')
def do():
logging.info('2222222 in b')
我可以看到日志输出:
INFO:root:11111111 in a
INFO:root:2222222 in b
很明显,这与注释行有关,但我本以为basicConfig()
会在导入b
模块后设置一些内容,但事实并非如此。
有人能解释一下这里发生了什么吗?
在配置日志记录系统之前,导入语句import b
已触发日志记录事件。当使用未配置的日志记录系统记录事件时,它会使用默认配置自动配置:stderr上级别为WARNING的流处理程序。
如果根记录器已经配置了处理程序,则随后的basicConfig
调用将不执行任何操作。因此,INFO级别的事件被过滤掉,因为根记录器配置了一个阈值更高的WARNING处理程序。
正确的解决方案是确保在配置日志记录系统之前不记录事件。通常这意味着避免记录事件或在全局(模块级别(范围内进行任何工作。
然而,由于Python 3.8,有一种变通方法可以强制重新配置日志系统:
logging.basicConfig(stream=sys.stdout, level=logging.INFO, force=True)
在较旧的Python版本中,您可以手动清除根日志处理程序:
del logging.getLogger().handlers[:]
logging.basicConfig(stream=sys.stdout, level=logging.INFO)
我怀疑这与如何配置输出有关。我不认为在.py中设置它会为两个文件都设置它,有点像你必须在两个文件中导入日志记录,否则会出错。
如果您将basicConfig行添加到b.py,那么您可以保留logging.info('11111 in b')
并看到它被打印出来。