使用utf-8-sig是因为它能自动跳过BOM(\ufeff),避免Excel保存的CSV文件首行出现隐形乱码,读写均对Excel友好;而utf-8不处理BOM,易导致列名错位或KeyError。

为什么用 utf-8-sig 而不是 utf-8
Windows 上用 Excel 保存的 CSV 文件,开头常带 BOM(Byte Order Mark),即三个字节 \ufeff。Python 默认的 utf-8 编码会把这仨字节当普通字符读进来,导致第一列列名或首行数据开头多出一个看不见的乱码(比如打印出来是 姓名 而非 姓名)。utf-8-sig 会自动跳过 BOM,读取时干净,写入时也默认加 BOM(对 Excel 友好)。
pandas 读 CSV 时指定 encoding='utf-8-sig'
这是最常见场景。不加 encoding 或错用 gbk、utf-8 都可能报错或显示乱码。
- 直接读取:用
pd.read_csv('data.csv', encoding='utf-8-sig') - 如果仍报
UnicodeDecodeError,说明文件实际是gbk(旧版 Windows 记事本常用),可试encoding='gbk',但优先确认来源——Excel 保存的 CSV 基本都是utf-8-sig - 写入时也建议显式指定:
df.to_csv('out.csv', encoding='utf-8-sig', index=False),否则 Excel 打开可能又乱码
csv 模块手动处理时怎么设 encoding
不用 pandas、纯用标准库时,csv.reader 和 csv.writer 本身不接受 encoding 参数,必须在 open() 层指定:
import csv
with open('data.csv', encoding='utf-8-sig') as f:
reader = csv.reader(f)
for row in reader:
print(row) # 第一列不会再有 \ufeff注意:不能写成 open('data.csv', encoding='utf-8') 后再丢给 csv.reader ——BOM 还在,只是没被跳过。
立即学习“Python免费学习笔记(深入)”;
如何快速判断文件真实编码和是否有 BOM
别靠猜。用命令行或 Python 快速验证:
- Linux/macOS:
file -i data.csv看 reported encoding;或xxd -l 10 data.csv查看前几个字节,ef bb bf就是 UTF-8 BOM - Python 中检查:
with open('data.csv', 'rb') as f: print(f.read(3)),输出b'\xef\xbb\xbf'即含 BOM - VS Code 打开右下角会显示当前编码,点击可切换并重载;Sublime Text 顶部菜单
File → Reopen with Encoding可试不同编码预览效果
BOM 是隐形问题,不打印、不报错,只让列名错位或匹配失败(比如 df['姓名'] 报 KeyError),容易卡很久才意识到是编码开头多了一坨字节。


















