Windows CMD运行Python脚本输出中文乱码怎么办
UnicodeEncodeError,核心原因在于终端默认代码页(通常为 GBK/CP936)与 Python 运行时的字节编码(UTF-8)不一致。解决该问题最直接有效的方法是开启 Python 的 UTF-8 运行模式,或者通过 chcp 65001 将 CMD 活动代码页切换为 UTF-8。
一、为什么 CMD 会输出中文乱码:字符流转与编码错位原理
计算机在处理文本时,内存中的字符串对象必须经过特定的编码规则转换成字节流,再由显示终端按照对应的解码规则还原为字符。Windows CMD 产生中文乱码,绝大多数情况下并不是代码语法错误,而是“发送端(Python 标准输出)”与“接收端(CMD 控制台缓冲区)”使用了不同的编码字典。
在简体中文版 Windows 系统中,CMD 默认采用代码页 936(即 GBK/CP936 编码),每个汉字通常用 2 个字节表示。现代 Python 3 源代码与内部字符串标准均默认基于 UTF-8,常用汉字在 UTF-8 下编码为 3 个字节。当 Python 将包含中文的 UTF-8 字节流直接写到控制台时,CMD 仍按每 2 个字节一组去 GBK 码表中查找文字,错位拼接后就会呈现出如“浣犲ソ”、“鏂囨湰”等无意义的乱码。
二、乱码现象分类与快速排查诊断
在终端中运行 Python 遇到中文问题时,表现形态通常分为三类。不同现象对应的问题根源不同,按现象选择解决路径能避免盲目尝试:
- 现象一:输出显示为串联乱码汉字(如“浣犲ソ”、“璇锋眰”)。这通常表明 Python 输出了正确的 UTF-8 字节,但 CMD 处于默认的 GBK 代码页,将其误当成 GBK 连续解码。
- 现象二:程序直接中断,抛出
UnicodeEncodeError: 'charmap' codec can't encode characters错误。在 Windows 下,当 Python 尝试将非 ASCII 字符或 emoji 表情符号编码到终端默认代码页却发现码表不包含对应字符时,就会抛出此异常。 - 现象三:输出显示为连续的问号“???”或方块乱码。这通常是因为源码文件本身保存时损坏、混杂了 ANSI/UTF-8 编码,或者 CMD 使用了不包含中文字形的光栅字体。
三、彻底解决中文乱码的四种具体方法
针对上述不同场景,以下按由简到繁、由临时到永久的顺序提供四种可操作的具体实施步骤。
方法一:在运行命令中加入 -X utf8 参数(最快临时方案)
Python 3.7 及以上版本引入了 PEP 540(UTF-8 模式)。只要在启动解释器时加上 -X utf8 参数,Python 就会强制将内部与控制台输入输出统一为 UTF-8,忽略操作系统默认的本地区域编码。
# 在 CMD 中直接执行
python -X utf8 your_script.py
适用场景:无需改动脚本代码,无需修改系统全局配置,适合临时执行或在排查阶段快速验证问题。
方法二:设置环境变量 PYTHONUTF8=1(最推荐的本地开发方案)
如果不想每次运行命令都手动敲入 -X utf8,可通过配置环境变量 PYTHONUTF8=1 让当前会话或整个 Windows 系统永久开启 UTF-8 模式。
-
在当前 CMD 窗口临时生效:
此命令仅对当前 CMD 窗口生效,关闭后失效。set PYTHONUTF8=1 python your_script.py -
在 Windows 系统中永久生效:
按快捷键
Win + R打开运行窗口,输入sysdm.cpl并回车打开“系统属性”;切换到“高级”选项卡,点击“环境变量”;在“用户变量”或“系统变量”区域点击“新建”,变量名填PYTHONUTF8,变量值填1;连续点击“确定”保存后,重新打开 CMD 即可。
方法三:在 CMD 中执行 chcp 65001(切换终端代码页)
chcp 是 Windows 控制台内置的代码页切换命令。默认情况下,简体中文 Windows 的代码页为 936。将其更改为 65001 即可将当前窗口的字符解释标准切为 UTF-8。
# 查看当前 CMD 代码页(通常返回“活动代码页: 936”)
chcp
# 切换为 UTF-8 代码页
chcp 65001
# 随后运行 Python 脚本
python your_script.py
特别注意:使用 chcp 65001 时,请右键点击 CMD 窗口标题栏选择“属性” -> “字体”,确保所用字体是 Lucida Console、新宋体 或其他 TrueType 矢量字体,不要使用旧式的“点阵字体/光栅字体”,否则即使代码页正确也会因字形缺失显示乱码。
方法四:在 Python 脚本开头重构输出流(脚本自适应)
如果你编写的脚本需要交付给其他团队成员或客户使用,无法强制要求每台电脑都去改环境变量,可以在代码内部主动重配标准输出与错误流编码:
import sys
# 适用于 Python 3.7+ 的标准重构方式
if sys.platform.startswith('win'):
sys.stdout.reconfigure(encoding='utf-8')
sys.stderr.reconfigure(encoding='utf-8')
print("中文测试:成功输出,无乱码!")
这段代码在 Windows 环境下检测到标准输出后,将编码显式重置为 utf-8,使得脚本自身具备对 Windows 环境的鲁棒性。
四、容易忽略的细节与避坑提醒
在 CMD 中,很多时候我们通过管道或重定向保存输出,例如 python test.py > output.txt。此时 Python 会认为标准输出并不是终端控制台,而是文件流。若未开启 PYTHONUTF8=1,Python 3 在 Windows 上仍可能采用 cp936 写入文件,导致用常见 UTF-8 文本编辑器打开该 txt 时同样显示为乱码。因此,配置系统级 PYTHONUTF8=1 能够同时保证控制台显示与重定向文件均采用标准的 UTF-8 编码。
切勿使用 Windows 自带的传统记事本编辑 Python 脚本。传统记事本在保存 UTF-8 时可能会强行插入 EF BB BF 三个字节的 BOM(Byte Order Mark)头。这会导致 Python 在解析第一行(如 #!/usr/bin/env python 或编码声明)时抛出语法异常。请始终使用专业编辑器(如 VS Code、Cursor、PyCharm 等)并确认右下角编码格式为 UTF-8(不带 BOM)。
传统的 cmd.exe 控制台宿主进程架构较为古老,对 Unicode 及复杂字符(如 ANSI 颜色、Emoji)支持有限。微软官方推出的 Windows Terminal 原生支持 UTF-8 字符集渲染与 GPU 文字加速。在 Windows 10/11 中,推荐将默认终端应用程序切换为 Windows Terminal,可从渲染层面消除绝大部分因字体和代码页带来的字符撕裂问题。
五、四种解决方案特性对比与选型建议
为了帮助读者根据不同的工作场景(例如本地快速调试、长期开发、交付第三方运行、批处理脚本自动化)快速选用最合适的方法,下表将各方案的生效范围、侵入性与适用场景进行横向对比:
| 解决方案 | 实施命令 / 方式 | 生效范围 | 侵入性 | 最佳适用场景 |
|---|---|---|---|---|
运行时参数 -X utf8 |
python -X utf8 script.py |
仅当前单次命令 | 零侵入,不改系统与代码 | 排查定位问题、临时调试、CI/CD 自动化流水线命令 |
环境变量 PYTHONUTF8 |
系统变量添加 PYTHONUTF8=1 |
全局所有 Python 脚本 | 无需修改代码 | 个人开发电脑、日常高频使用 Python 的主力环境(最推荐) |
终端代码页 chcp 65001 |
CMD 执行 chcp 65001 |
当前 CMD 窗口会话 | 仅影响控制台环境 | 需要在 CMD 中混合运行其他控制台工具或批处理脚本(.bat) |
代码流重置 reconfigure |
sys.stdout.reconfigure(...) |
仅当前 Python 脚本 | 需要改动脚本源代码 | 分发给外部用户运行的独立工具脚本、无法要求用户配置环境时 |
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













