Python包开发中logging模块行为不一致问题排查
Python包中logging模块行为不一致问题分析与解决
最小可复现示例(MRE)
my_package/init.py
import logging from . import module, a_second_module logging.basicConfig(level=logging.INFO)
my_package/module.py
import logging def module(): logging.info("Doing something...") logging.debug("This is a debug message and won't show up by default.")
my_package/a_second_module.py
import logging from my_package_test_so_poetry.module import module logging.warning("Warning from a_second_module.py") def module2(): module() print("Doing something else...")
执行步骤与异常现象
执行以下终端操作:
python # 进入Python控制台 from my_package.module import module module()
实际仅输出:
WARNING:root:Warning from a_second_module.py
缺少module函数应输出的INFO:root:Doing something...日志。
问题根源分析
根据Python官方文档说明:
在根记录器上记录一条严重级别为'WARNING'的消息。如果记录器没有处理器,会调用basicConfig()添加一个预定义格式的控制台处理器。
核心问题在于**logging.basicConfig()仅在根记录器无任何处理器时才会生效**,导入顺序触发了意外的自动初始化:
- 执行
from my_package.module import module时,Python先加载my_package/__init__.py __init__.py先执行from . import module, a_second_module,触发a_second_module.py的加载a_second_module.py顶层的logging.warning(...)执行时,根记录器还没有处理器,Python自动调用默认basicConfig(),给根记录器绑定了级别为WARNING的控制台处理器- 后续
__init__.py中的logging.basicConfig(level=logging.INFO)因根记录器已有处理器,完全不生效 - 调用
module()时,INFO级别日志低于根记录器当前的WARNING级别,因此被过滤不输出
解决方案
方案1:提前配置logging,避免自动初始化
修改__init__.py,把logging配置放到模块导入之前:
import logging # 先完成logging配置,再导入其他模块 logging.basicConfig(level=logging.INFO) from . import module, a_second_module
方案2:直接修改根记录器级别(适配无法调整导入顺序的场景)
绕过basicConfig()的限制,直接给根记录器设置级别:
import logging from . import module, a_second_module # 强制设置根记录器级别,不受已有处理器影响 logging.getLogger().setLevel(logging.INFO)
方案3:避免模块顶层输出日志
把a_second_module.py中的顶层日志输出移到函数内部,仅在调用时触发:
import logging from my_package_test_so_poetry.module import module def module2(): logging.warning("Warning from a_second_module.py") module() print("Doing something else...")
内容的提问来源于stack exchange,提问作者FluidMechanics Potential Flows
相关产品推荐
相关产品推荐

