本文整理自一段真实的排错对话:项目里反复踩到中文列名乱码、Python 脚本注释乱码、后端日志乱码,最后延伸到日常使用中打开文档/记事本乱码的通病。把”乱码”这件事一次性讲透。

你一定遇到过:用记事本打开一个文件,满屏 涓囧悕;Python 跑起来报 SyntaxError: Non-UTF8;Excel 打开 CSV 中文全变方块;CMD 里 print("中文") 输出一堆问号。

这不是文件坏了,而是编码(encoding)在作怪。本文从根源讲起,给你一套解决方案。


0. 一句话搞懂:乱码到底是什么

文本在磁盘/内存里本质是字节(bytes)

  • 保存时:字符 → 字节(按编码 A)
  • 打开时:字节 → 字符(按编码 B)

A ≠ B,同一串字节被错误解读,就显示为乱码。

中文字符最常见的两对编码:

编码 是什么 典型场景
GBK / GB18030 Windows 中文系统传统默认 记事本、老程序、CMD 默认
UTF-8 现代通用万国码 Linux / macOS、Web、Python 源码、MySQL utf8mb4

举例:姓名 用 UTF-8 存是 6 个字节,用 GBK 解读就会变成 濮撳悕 这类天书。

核心结论:乱码 = 保存编码与打开编码不一致。根治办法是全链路统一用 UTF-8


1. 日常场景逐个击破

1.1 记事本打开乱码

记事本默认按**系统区域编码(GBK)**猜测打开,遇到 UTF-8(无 BOM)文件就翻车。

解法

  • 打开时:文件 → 打开,右下角编码选 UTF-8;或”另存为”时编码选 UTF-8。
  • 根本建议:换 VS Code / Notepad++,能自动识别 UTF-8 与 GBK,几乎不踩坑。VS Code 右下角可”通过编码重新打开”。

1.2 脚本注释乱码(Python 踩坑重灾区)

.py 文件里写了中文注释,若文件存成 GBK 而 Python 用 UTF-8 读,会直接 SyntaxError: Non-UTF8 code ...

解法

  • Python 3 默认源码编码是 UTF-8,写 .py 时确保编辑器保存为 UTF-8(无 BOM)
  • 老文件可加首行声明(兼容+提醒):# -*- coding: utf-8 -*-(Python 3 其实多余,但能提醒人和工具)。
  • 读取外部文件时做多编码 fallback(见第 3 节)。

1.3 打开文档:CSV / Excel / Word 乱码

CSV 乱码最常见:Excel 默认用系统编码(GBK)打开 CSV,UTF-8 的 CSV 就乱码。

解法

  • Excel:数据 → 从文本/CSV 导入时手动选 UTF-8 编码
  • 生成 CSV 时带 UTF-8 BOM,Excel 靠 BOM 识别 → 写 encoding="utf-8-sig"(见下)。
  • .xlsx / .docx 是 zip+XML,自带编码声明,一般不乱码;乱码多在”导入文本”环节。

1.4 终端 / 命令行输出乱码

Windows 老控制台默认 CP936(GBK),Python print 中文 UTF-8 输出可能乱码。

解法

  • 临时切 UTF-8:chcp 65001
  • 或设环境变量:PYTHONIOENCODING=utf-8
  • Windows Terminal(默认 UTF-8)替代老 cmd。
  • 稳招:把输出 > file 2>&1 落文件再读,绕开终端编码问题。

2. Windows 系统级”一键 UTF-8”开关

这是很多人忽略的治本开关:让整个系统的非 Unicode 程序默认编码从 GBK 变成 UTF-8。

2.1 打开路径

  1. Win + R → 输入 intl.cpl → 回车(直接打开”区域”)。
  2. 切到 “管理” 选项卡。
  3. “更改系统区域设置…”(需管理员权限)。
  4. 勾选:

    Beta: 使用 Unicode UTF-8 提供全球语言支持
    (Beta: Use Unicode UTF-8 for worldwide language support)

  5. 确定 → 重启电脑生效。

开启后,记事本、老程序、CMD 默认按 UTF-8 解读,日常乱码大幅减少。

2.2 副作用(先知道再决定)

这个选项改的是**”非 Unicode 程序”(ANSI/系统区域)的默认代码页**:

  • ✅ CMD / PowerShell 默认代码页变 65001(UTF-8),后端日志中文不再乱。
  • ⚠️ 个别老国产业务软件(老版财务、报税、工控)写死 GBK,开启后反而可能显示乱码。
  • ⚠️ 它只改”系统默认猜测编码”,文件本身存成什么编码还是什么编码——一个纯 GBK 老文件在 UTF-8 系统里用记事本开,仍可能乱。

建议

  • 日常主要用 VS Code / 浏览器 / Python / Web → 可以勾,利大于弊。
  • 电脑跑关键老业务软件 → 先确认兼容,出问题就取消勾、重启回退。
  • 最稳组合:勾这个选项 + 用 VS Code(自动识别编码),记事本基本可退休。

3. 一套可落地的防乱码规范

把下面几条变成习惯,乱码基本绝迹:

  1. 所有文本文件一律 UTF-8 无 BOM 保存(改编辑器默认设置)。
  2. CSV 要 Excel 直接双击打开 → 用 utf-8-sig(带 BOM);不进 Excel → 纯 utf-8
  3. Python 读外部文件做多编码 fallback
    1
    2
    3
    4
    5
    6
    7
    def read_text(path):
    for enc in ("utf-8", "utf-8-sig", "gb18030"):
    try:
    return open(path, encoding=enc).read()
    except UnicodeDecodeError:
    continue
    raise ValueError(f"无法解码: {path}")
  4. MySQL 连接串加 charset=utf8mb4,库表用 utf8mb4
  5. 终端:能换 Windows Terminal 就换;不能换就 chcp 65001 或设 PYTHONIOENCODING=utf-8

3.1 一键转码小工具

不确定某文件什么编码、想转成 UTF-8:

1
2
3
4
5
6
7
8
9
10
11
F:\Miniconda\envs\agent-project\python.exe -c "
import sys
p = sys.argv[1]
for enc in ('utf-8','gb18030','utf-8-sig'):
try:
t = open(p, encoding=enc).read()
open(p, 'w', encoding='utf-8').write(t)
print('converted from', enc); break
except UnicodeDecodeError:
pass
" 你的文件.txt

4. 实战小结(来自项目排错)

在一个 Agent 项目里,中文乱码曾以多种形式出现:

  • 数据库中文列名(姓名/性别/部门):脚本用 COLUMN_ALIASES 做别名兼容,读取时多编码 fallback,端到端跑通。
  • Python 子进程缺包 + 编码:确认子进程用的是哪个 Python(conda / 全局),并统一 UTF-8。
  • CSV 导出给 Excel:改用 utf-8-sig 避免双击乱码。
  • 终端日志:落文件读,绕开控制台编码。

统一编码后,这些问题全部消失。


5. 记住这三句话

  1. 乱码不是文件坏了,是编码对不上。
  2. 保存与打开用同一套编码(首选 UTF-8)。
  3. 系统开关 + 编辑器设置 + 代码里多编码兼容 = 三重保险。

把”全链路 UTF-8”变成习惯,你会发现乱码这种低级问题,从此不再出现。