Python文本处理核心是明确字符串为Unicode、传输为字节,跨平台问题源于默认编码、换行符和BOM差异;须显式指定encoding,区分utf-8与utf-8-sig,注意系统locale及终端编码设置。

Python处理文本时,编码与解码的核心是明确“字符串在内存中是Unicode,而文件或网络传输时是字节”,跨平台问题(尤其是Windows与Linux/macOS之间)主要源于默认编码不同、换行符差异和BOM处理不一致。关键不是记住所有编码名,而是建立“源头→字节→目标”的清晰链条。
搞清你的Python版本和系统默认编码
Python 3中,str类型是Unicode字符串,bytes类型是原始字节,这是根本前提。跨平台出错往往始于误以为str就是“能直接写入文件的格式”。运行以下代码快速确认环境:
-
import sys; print(sys.getdefaultencoding()) → 通常是
utf-8(Python 3.7+),但旧版Windows可能显示mbcs(即系统ANSI编码,如GBK) -
import locale; print(locale.getpreferredencoding()) → Windows常为
cp936(GBK),Linux/macOS多为UTF-8 - open('test.txt', 'w').write('你好'); open('test.txt', 'rb').read() → 观察实际写入的字节,验证默认行为
读写文件时必须显式指定encoding参数
不加encoding参数等于依赖系统默认值,这正是跨平台崩坏的起点。尤其注意Windows记事本默认用UTF-8带BOM保存,而Python用utf-8打开会把BOM当成字符;用utf-8-sig则自动剥离BOM。
- 安全写法:with open('data.txt', 'w', encoding='utf-8') as f: f.write('中文')
- 兼容记事本:with open('note.txt', 'r', encoding='utf-8-sig') as f: text = f.read()(自动去BOM)
- 读取旧Windows文件(GBK):with open('old.txt', 'r', encoding='gbk') as f: text = f.read()
- 避免陷阱:open('x.txt', 'w').write(...)(无encoding)在Linux写UTF-8,在Windows可能写GBK,别人打不开
网络请求和终端输出需单独处理
requests库默认按HTTP头或HTML meta推断编码,但不可靠;终端(cmd/PowerShell/Terminal)的编码设置独立于Python,导致print乱码。
立即学习“Python免费学习笔记(深入)”;
- requests获取网页后,优先用
r.apparent_encoding或r.encoding,再手动decode:r.content.decode('gbk')(如遇到中文网页未声明编码) - Windows命令行显示乱码:在脚本开头加import io; import sys; sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8'),或启动时用
chcp 65001 - Linux/macOS终端一般没问题,但若ssh到某服务器显示异常,检查
locale输出是否含UTF-8
调试乱码:三步定位法
看到“”、“锟斤拷”或一串问号?别猜,用字节视角看真相:
- 打印原始字节:print(repr(text.encode('latin-1')))(latin-1可编码任意字节,不会报错)
- 反向验证解码:b'\xe4\xbd\xa0'.decode('utf-8') → '你',若报错说明字节不是UTF-8
- 查编码表:WHATWG Encoding Standard查常见编码对应关系,比如
\xa3\xa3在GBK里是“你好”,在UTF-8里是非法字节










