根本原因是终端环境(如lang=c)导致python将unicode字符串编码为ascii,遇中文报错;解决方法包括设置pythonioencoding=utf-8、显式指定open()的encoding参数、用textiowrapper包装sys.stdout以确保utf-8输出。

为什么print("中文")在Linux终端会报UnicodeEncodeError
根本原因是Python 3内部用Unicode,但终端环境(比如LANG=C或LC_ALL=POSIX)默认不支持UTF-8输出。Python尝试把Unicode字符串encode成系统默认编码(通常是ASCII),遇到中文就崩了。
检查当前终端编码:locale;如果输出里没有UTF-8字样(比如显示LANG=C),这就是病根。
- 临时修复:运行
export LC_ALL=en_US.UTF-8(需系统已安装该locale) - 更稳妥做法:直接设
export PYTHONIOENCODING=utf-8,强制Python标准流走UTF-8 - 避免改系统locale时出错:优先用
PYTHONIOENCODING,它只影响当前Python进程
open()读写中文文件必须显式指定encoding参数
Python 3的open()在文本模式下**不再有默认编码**,不写encoding就依赖系统locale——这在Windows(GBK)、Linux(可能C locale)、macOS(通常UTF-8)上行为不一致,极易出错。
Python 3.14.2是Python编程语言在2025年12月5日发布的稳定版本,属于3.14系列的第二个维护更新。该版本包含了18项修复,重点解决了多进程、数据类及正则表达式等模块的回归问题,并修复了CVE-2025-12084等安全漏洞。此版本标志着自由线程模式(移除GIL)正式获得官方支持,是Python发展的重要里程碑。
- 写文件:一律用
with open('out.txt', 'w', encoding='utf-8') as f: - 读文件:先确认来源编码,常见情况:
encoding='gbk'(Windows记事本保存的中文)、encoding='utf-8-sig'(带BOM的UTF-8)、encoding='gb18030'(兼容GBK且更健壮) - 别信
encoding='utf-8'万能:很多中文CSV是GBK,硬读会直接UnicodeDecodeError
chardet探测结果不能直接信,得加置信度判断
chardet.detect()返回的confidence值低于0.7时,大概率不准——尤其对小文件、纯数字/英文混少量中文、或空行多的文件。
- 安全做法:先读前10KB二进制数据,再检查
result['confidence'] > 0.9才采用result['encoding'] - fallback策略:准备
['utf-8-sig', 'gb18030', 'latin-1']列表,逐个try/except打开,latin-1作为兜底(它不会报错,但可能乱码) - 注意:
chardet对UTF-16/UTF-32识别较弱,若文件开头有\xff\xfe或\xfe\xff,直接按utf-16处理更稳
sys.stdout重定向时中文容易丢,用TextIOWrapper包装更可靠
当脚本输出被重定向(如python script.py > out.txt)或接入日志框架时,sys.stdout可能变成二进制buffer,导致print()内部encode失败。
- 手动修复:在脚本开头加
import sys, io; sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') - 比
PYTHONIOENCODING更底层,能覆盖重定向场景 - 副作用:会影响其他依赖
sys.stdout行为的库(如某些进度条),用前先测
真正麻烦的不是报错本身,而是同一段代码在你本地IDE跑通、扔到服务器就挂——根源几乎全是环境编码没对齐。盯住locale、open()的encoding、和重定向这三处,90%的中文编码问题就消停了。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










