在 Windows 11 环境下,通过 Claude Code 的 Bash 工具执行 Python 命令时,输出的中文字符全部显示为乱码:

$ python -c "print('测试中文输出')"
�����˺Ž�����������
英文和符号正常,唯独中文变成了一堆问号和方块。
这是一个经典的 编码不匹配 问题,涉及三层编码链路:
Python stdout → 终端(Claude Code Bash工具) → 显示
| 环节 | 编码 | 说明 |
|---|---|---|
| Windows 系统默认 | GBK (CP936) | 中文 Windows 的系统 locale 编码 |
| Python stdout | 跟随系统 | 默认使用 locale.getpreferredencoding(),即 GBK |
| Claude Code Bash 工具 | UTF-8 | 期望接收 UTF-8 编码的字节流 |
问题根因:Python 用 GBK 编码输出中文,但 Claude Code 的终端按 UTF-8 解读这些字节,编码不匹配导致乱码。
简单来说:
GBK 编码的「你」是 xc4xe3,UTF-8 解读这俩字节变成了 ��。
| 方案 | 原理 | 优点 | 缺点 |
|---|---|---|---|
PYTHONIOENCODING=utf-8 环境变量 | 强制 Python stdout 使用 UTF-8 | 一劳永逸,不侵入代码 | 需要重启终端生效 |
每次命令前加 chcp 65001 | 切换控制台代码页 | 无需改环境变量 | 每次都要加,且对 Git Bash 不一定生效 |
代码内 sys.stdout 重包装 | Python 内部强制编码 | 精确控制 | 侵入性强,每个脚本都要改 |
推荐方案:设置 PYTHONIOENCODING=utf-8 环境变量。
打开 PowerShell(普通权限即可),执行:
New-ItemProperty -Path 'HKCU:Environment' -Name 'PYTHONIOENCODING' -Value 'utf-8' -PropertyType String -Force
验证是否写入成功:
[System.Environment]::GetEnvironmentVariable('PYTHONIOENCODING', 'User')
# 输出: utf-8
为什么用注册表而不是 PowerShell 的 SetEnvironmentVariable?
实测发现通过 [System.Environment]::SetEnvironmentVariable() 设置的用户级环境变量,在某些环境下(如 Claude Code 的 Bash 工具)不会被新进程继承。直接写注册表 HKCU:Environment 更可靠。
环境变量在进程启动时继承,必须重启当前终端或 Claude Code,新值才会生效。
$ python -c "print('你好世界 ✅')"
你好世界 ✅
中文正常显示,乱码问题解决。
PYTHONIOENCODING=utf-8 会影响所有 Python 进程的 stdout/stderr 编码。对于大多数场景这是期望行为,但如果你有脚本依赖 GBK 输出(比如写文件给老系统读),需要注意。~/.bashrc 中添加:export PYTHONIOENCODING=utf-8
但这只对交互式 Shell 生效,Claude Code 的 Bash 工具跑的是非交互模式,所以不一定有用。注册表方式更可靠。
| 项目 | 内容 |
|---|---|
| 问题 | Windows 下 Bash 调用 Python 输出中文乱码 |
| 根因 | Python 默认 GBK 编码 vs 终端 UTF-8 编码不匹配 |
| 解决 | 注册表设置 PYTHONIOENCODING=utf-8,重启生效 |
| 验证 | python -c "print('你好世界 ✅')" 正常输出 |