假设我有以下 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
,但是当我从 logging.info('11111 in b')
中注释掉 b.py
时,如下所示:
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
模块后直接设置一些内容,但事实并非如此。
有人可以解释一下这里发生了什么吗?
答案 0 :(得分:2)
导入语句 import b
在日志系统被配置之前触发了一个日志事件。当使用未配置的日志系统记录事件时,它会使用默认配置自动配置:stderr 上级别为 WARNING 的流处理程序。
如果根记录器已经配置了处理程序,则后续的 basicConfig
调用不会执行任何操作。因此,INFO 级别的事件被过滤掉,因为根记录器配置了一个处理程序,其阈值为 WARNING。
正确的解决方案是确保在配置日志系统之前不会记录事件。通常这意味着避免日志事件或在全局(模块级别)范围内执行任何工作。
但是,since 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)
答案 1 :(得分:0)
我怀疑这与输出的配置方式有关。我不认为在 a.py 中设置它会为两个文件设置它,有点像你必须在两个文件中导入日志,否则会出错。
如果您将 basicConfig 行添加到 b.py,那么您可以保留您的 logging.info('11111 in b')
并看到它打印出来。