str.encode() / bytes.decode() 时报 UnicodeEncodeError/UnicodeDecodeError 的解决

Unicode编码错误本质是编解码不匹配,须明确数据源编码(如GBK/UTF-8/GB2312),显式指定encoding参数,优先用open()的encoding自动处理,避免依赖默认值或errors兜底。

遇到 UnicodeEncodeErrorUnicodeDecodeError,本质是编码不匹配:Python 尝试用错误的字符编码去转换字符串和字节。关键不是“怎么绕过去”,而是“明确知道该用什么编码”。

搞清数据原本的编码

错误常发生在读文件、收网络响应、处理用户输入时——Python 不会自动猜编码。比如:

  • Windows 记事本默认存为 GBK(中文环境),不是 UTF-8;
  • 某些旧系统日志、Excel 导出的 CSV 可能是 GB2312ISO-8859-1
  • HTTP 响应头没声明 charsetrequests 可能误判为 ISO-8859-1。

解决方法:查源头。看文件保存时选的编码、HTTP 的 Content-Type 头、文档说明,或用命令行工具如 file -i filename(Linux/macOS)粗略判断。

显式指定 encode/decode 的 encoding 参数

别依赖默认值。UTF-8 是推荐,但不是万能:

  • '你好'.encode('utf-8') → 正确;
  • '你好'.encode('ascii') → 报 UnicodeEncodeError(ASCII 不支持中文);
  • b'\xc4\xe3\xba\xc3'.decode('utf-8') → 报 UnicodeDecodeError(这是 GBK 编码的“你好”,用 UTF-8 解会错);
  • b'\xc4\xe3\xba\xc3'.decode('gbk') → 正确。

写代码时,只要涉及 .encode().decode(),就手动写上 encoding='xxx',不省略。

容错处理:errors 参数不是捷径,而是兜底

errors='ignore''replace' 能让程序不崩溃,但会丢失或污染数据:

  • 'café'.encode('ascii', errors='ignore')b'caf'(é 消失了);
  • b'\xff\xfe'.decode('utf-8', errors='replace')''(乱码符号)。

仅在明确接受信息损失时使用,例如日志清洗、临时调试。生产环境优先修复编码来源,而不是掩盖问题。

读写文件时用 open() 的 encoding 参数

避免手动调用 .encode()/.decode()。直接让 open() 处理:

  • 读文件:with open('f.txt', encoding='gbk') as f:

    text = f.read()
  • 写文件:with open('f.txt', 'w', encoding='utf-8') as f: f.write('你好')

这样 Python 自动完成编解码,不用自己转字节再 decode,大幅降低出错概率。

不复杂但容易忽略:编码问题不是异常要 catch,而是逻辑要对齐。