Python官方文档日志示例代码无法写入文件的问题排查
问题原因及解决方案
核心原因
你遇到的所有问题本质都是**logging.basicConfig的调用时机错误**,以及Python终端环境下存在的隐式日志初始化行为:
logging.basicConfig仅会在root logger未被初始化时生效,你先调用logging.getLogger(__name__)获取子logger,此时终端环境的底层操作可能已触发root logger的隐式初始化,导致后续的basicConfig配置完全失效。- 子logger默认继承root logger的配置,但root logger未被正确配置时,子logger就没有有效的handler和级别设置,自然无法输出日志。
- IPython环境未触发这种隐式初始化,所以先getLogger再basicConfig的代码能正常运行,但这属于环境特例,不符合logging模块的规范用法。
针对性解决方案
1. 修复日志写入文件问题
调整代码顺序,先调用logging.basicConfig,再获取logger实例,这是logging模块的标准用法:
import logging # 先配置root logger logging.basicConfig(filename='./test.log', level=logging.DEBUG) # 再获取子logger logger = logging.getLogger(__name__) logger.debug('This message should go to the log file') logger.info('So should this') logger.warning('And this, too') logger.error('And non-ASCII stuff, too, like Øresund and Malmö') print(logger.handlers)
此时子logger会继承root logger的FileHandler和级别设置,日志会正常写入test.log。
2. 解决logger.handlers为空、手动添加handler无效的问题
如果必须在getLogger之后配置,不要依赖basicConfig,直接给子logger添加handler并设置级别:
import logging logger = logging.getLogger(__name__) # 避免重复添加handler(多次运行时) if not logger.handlers: logger.setLevel(logging.DEBUG) handler = logging.FileHandler('./test.log') formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) logger.addHandler(handler) logger.debug('This message should go to the log file') # ... 其他日志输出
注意判断if not logger.handlers,防止多次运行时重复添加handler导致日志重复输出。
3. 解决移除配置后warning/error不输出的问题
完全移除配置代码时,root logger默认级别是logging.WARNING,但终端环境可能隐式修改了root logger级别,导致warning/error不输出。可以显式配置root logger:
import logging # 显式配置root logger的级别和控制台handler logging.basicConfig(level=logging.WARNING) logger = logging.getLogger(__name__) logger.warning('This will show up') logger.error('This will also show up')
关键注意事项
- 永远遵循先配置,后获取logger的顺序,这是避免logging模块大部分异常问题的核心。
- 不要依赖IPython等交互式环境的特例行为,终端脚本的日志配置必须严格遵循模块规范。
内容的提问来源于stack exchange,提问作者a_member
相关产品推荐
相关产品推荐

