本地读配置文件正常,部署到容器里报 UnicodeDecodeError 'ascii' codec can't decode byte 0xe4,同一个文件同一段代码。乍看像缓存或者权限的锅,追下去往往不是。
python -c "import locale; print(locale.getpreferredencoding(False))"
PYTHONUTF8=1 python app.py
grep -rn "open(" --include='*.py' | grep -v encoding
追下去是这么回事:open 不指定 encoding 时用 locale.getpreferredencoding(),容器里 LANG 没设就是 ANSI_X3.4-1968,也就是 ASCII。开发机是 UTF-8 所以看不出问题。
碰到「Python 默认编码」这类问题,我习惯先把当前配置原样备份一份,改坏了立刻换回来,不用现场推。测试环境和线上的差别,往往就在版本号和那几行被忽略的配置上。
线上出问题先对时间点,跟发布、备份、任务执行的时刻排一排,能省掉一半功夫。日志级别临时调高可以,记得改回去,长期开着既占磁盘又掩盖真问题。
权限不要一口气开到最大,先加到够用再往上试,范围小才好收。把复现步骤压到三条以内,交给同事也能跑出来,才算真的定位清楚。
具体做法是,所有 open 显式写 encoding='utf-8';用 pathlib 的 read_text 同样要传 encoding;容器里设 LANG=C.UTF-8 兜底;CI 加一条检查 禁止无 encoding 的 open。
验收就看一点,容器里读取不再报 UnicodeDecodeError 开发机和容器输出一致。
