ubuntu/debian系统中lang未设为utf-8导致print输出乱码,根本原因是终端按lang指定编码渲染utf-8字节,若lang=c或非utf-8则显示为æ–‡等乱码;需通过locale验证,临时执行export lang=en_us.utf-8,永久在~/.bashrc中添加export lang=en_us.utf-8和export lc_all=en_us.utf-8。

Ubuntu/Debian系统中LANG未设为UTF-8导致print输出乱码
Linux终端本身不“懂”UTF-8,它只按当前LANG环境变量指定的编码渲染字节。如果LANG=C或LANG=en_US.UTF-8缺失,Python的print("中文")会把UTF-8字节直接扔给终端,而终端用ASCII或latin-1解释,结果就是æ–‡这类乱码。
验证方式:运行locale,若输出中LANG=为空或不是*UTF-8结尾,就是根源。
- 临时修复:执行
export LANG=en_US.UTF-8(或zh_CN.UTF-8,需先locale -a | grep zh_CN.utf8确认存在) - 永久生效:在
~/.bashrc末尾追加两行:export LANG=en_US.UTF-8export LC_ALL=en_US.UTF-8 - 注意:
LC_ALL优先级高于LANG,设了LC_ALL就不用管LANG;但某些系统(如旧版Ubuntu)默认没装en_US.UTF-8locale,需先运行sudo locale-gen en_US.UTF-8
Windows命令行(cmd/powershell)中Python输出中文变问号或方块
Windows cmd默认用GBK(即cp936)编码,而Python 3脚本内部字符串是Unicode,print()时会尝试用控制台当前代码页编码输出。若代码页不是65001(UTF-8),就会失败。
查当前代码页:运行chcp,输出活动代码页: 936即为GBK。
- 临时切换:运行
chcp 65001(启用UTF-8),再启动Python —— 此时print("中文")能正常显示 - PowerShell用户更推荐:在PowerShell中执行
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8,避免每次手动chcp - 不建议改Python源码或全局
sitecustomize.py来绕过——这治标不治本,且可能破坏其他依赖GBK的模块(如某些Windows API封装)
Python读写文件时因未显式指定encoding参数引发的乱码
这是最隐蔽也最高频的问题:open()不带encoding参数时,Python用locale.getpreferredencoding()决定编码。该函数返回值受系统LANG影响,在Windows上常是cp936,Linux上可能是ANSI_X3.4-1968(即ASCII),根本不是UTF-8。
现象:用PyCharm或VS Code写的UTF-8文件,在终端里python script.py运行时open("data.txt").read()报UnicodeDecodeError,或读出来是乱码。
- 必须显式写
encoding="utf-8":哪怕你100%确定文件是UTF-8,也不依赖默认值 - 写文件同理:
open("out.txt", "w", encoding="utf-8"),否则可能生成GBK编码文件,跨平台打开就乱 - 例外情况:二进制模式
open(..., "rb")不涉及编码,无需encoding参数
chardet检测结果不准时该怎么 fallback
chardet或charset-normalizer对短文本、无BOM、混合编码的文件容易误判,比如把GBK内容识别成ISO-8859-1,再按此解码就雪上加霜。
真正鲁棒的做法不是“信检测结果”,而是构建可恢复的解码链:
- 先试
utf-8(带errors="strict") - 失败后试
gbk(中国场景下第二大概率) - 再失败试
gb2312(兼容老GB2312文件) - 最后用
latin-1兜底(它能1:1映射任意字节,不会抛异常,适合后续人工判断) - 不要用
errors="ignore"或"replace"——它们掩盖问题,让乱码变成静默丢失
真正难的从来不是“怎么修”,而是“怎么知道它本来是什么”。一旦原始编码丢失,所有修复都是概率游戏;所以从源头强制统一用UTF-8 + 显式声明,比事后补救可靠得多。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











