应先用 file -i 或 chardet 探测文件真实编码,再用 open() 指定 encoding(如 'gb18030')和 errors 参数(如 'replace'),优先采用 utf-8 并记录编码来源以避免探测不可靠问题。

直接用 codecs.open() 指定正确编码即可,但必须先知道文件真实编码;盲目试错或硬设 'utf-8' 会触发 UnicodeDecodeError 或静默乱码。
怎么判断文件实际编码?
不能靠文件扩展名或编辑器默认行为。Windows 记事本保存的文本常为 gbk 或 gb2312,Linux 下可能是 iso-8859-1 或 utf-8-sig。推荐组合使用:
- 用命令行工具快速探测:
file -i filename.txt(Linux/macOS)或chardet filename.txt(需 pip install chardet) - 在 Python 中试探性读取前 1000 字节:
chardet.detect(open('f.txt', 'rb').read(1000)) - 若检测结果是
{'encoding': 'GB2312', 'confidence': 0.99},就优先试'gb18030'(它是gb2312的超集,兼容性更好)
codecs.open() 的关键参数和常见错误
codecs.open() 本质是绕过内置 open() 的编码自动推断,强制指定解码方式。最容易出错的是忽略 errors 参数:
- 不设
errors:遇到无法解码字节直接抛UnicodeDecodeError - 设
errors='ignore':跳过坏字节,可能导致文字缺失(比如“你好世界”变成“你好世”) - 设
errors='replace':替换成 ,便于定位问题位置 - 正确做法:先用
errors='strict'确认编码无误,再切到业务需要的策略 - 示例:
codecs.open('data.txt', 'r', encoding='gb18030', errors='replace')
比 codecs.open() 更现代的替代方案
codecs 模块已逐渐被弃用。Python 3.7+ 推荐直接用内置 open(),它支持全部相同参数:
立即学习“Python免费学习笔记(深入)”;
-
open('f.txt', 'r', encoding='gb18030', errors='replace')功能完全等价,且更轻量 - 唯一例外是处理 BOM:若文件以
utf-8-sig编码保存(带 BOM),必须显式写encoding='utf-8-sig',否则首行多出\ufeff - 若需统一处理多种编码,别写一堆
try/except套codecs.open(),改用pathlib.Path().read_text(encoding=...)配合chardet探测更清晰
真正麻烦的不是选哪个函数,而是编码探测本身不可靠——特别是混合编码或损坏文件。生产环境建议记录原始编码来源,或强制上游统一输出 utf-8。


















