Python设置locale后logging模块无法生成日志的原因及解决方法
Python 3.9设置locale后logging崩溃的原因与修复方案
问题原因
错误码0xC0000374是Windows系统特有的堆内存损坏错误,根源在于logging模块的时间格式化逻辑与locale切换的冲突:
logging.basicConfig初始化时,会基于当前系统locale创建时间格式化器,底层依赖C标准库的strftime函数处理%(asctime)s字段。- 后续调用
locale.setlocale(locale.LC_ALL, "zh_CN.UTF-8")切换全局locale后,C层的strftime内部状态被修改,但logging已初始化的格式化器仍持有旧的内存缓冲区或状态引用,导致时间格式化时触发堆损坏,直接终止程序。 - 你导入的
time.asctime并未直接参与logging的时间处理,但核心冲突点确实是locale切换对时间格式化函数的影响。
修复方案
方案1:先设置locale再初始化logging
将locale配置放在logging.basicConfig之前,让logging初始化时直接使用目标locale,避免后续切换导致的状态不一致:
import logging import locale # 优先设置locale locale.setlocale(locale.LC_ALL, "zh_CN.UTF-8") logging.basicConfig( level=logging.INFO, filename="test.log", encoding="utf-8", filemode="w", format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', datefmt="%Y-%m-%d %H:%M:%S" ) logging.info("before") logging.info("after")
方案2:自定义时间格式化函数,绕过系统strftime
用Python原生的datetime模块实现时间格式化,替换logging默认的依赖系统locale的formatTime方法,彻底隔离locale影响:
import logging import locale from datetime import datetime def custom_time_formatter(record, datefmt=None): return datetime.now().strftime(datefmt or "%Y-%m-%d %H:%M:%S") logging.basicConfig( level=logging.INFO, filename="test.log", encoding="utf-8", filemode="w", format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', datefmt="%Y-%m-%d %H:%M:%S" ) # 替换默认的时间格式化逻辑 logging.Formatter.formatTime = lambda self, record, datefmt=None: custom_time_formatter(record, datefmt) logging.info("before") locale.setlocale(locale.LC_ALL, "zh_CN.UTF-8") logging.info("after")
方案3:仅设置必要的locale类别
如果不需要全局切换所有locale类别,只设置业务需要的类别(比如LC_CTYPE用于字符编码处理),避免修改LC_TIME(时间格式化相关的locale):
import logging import locale logging.basicConfig( level=logging.INFO, filename="test.log", encoding="utf-8", filemode="w", format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', datefmt="%Y-%m-%d %H:%M:%S" ) logging.info("before") # 仅设置字符编码相关的locale,不影响时间格式化 locale.setlocale(locale.LC_CTYPE, "zh_CN.UTF-8") logging.info("after")
内容的提问来源于stack exchange,提问作者Shilong Duan
相关产品推荐
相关产品推荐

