Python 3中必须显式编码/解码:str为Unicode文本,bytes为字节序列,二者不可自动转换;文件IO需指定encoding(推荐utf-8),跨平台应避免依赖系统默认编码。
Python处理文本时,编码与解码不是可选项,而是必须明确的步骤。尤其在跨平台(Windows/Linux/macOS)或读写文件、网络传输、终端交互等场景中,编码不一致会直接导致乱码、UnicodeDecodeError或UnicodeEncodeError。核心原则是:**字节(bytes)与字符串(str)不可混用,转换必须显式指定编码**。
Python 3中,str类型表示Unicode字符串(即抽象文本),bytes类型表示原始字节序列。两者不能自动互转——这和Python 2有本质区别。任何从文件、网络、终端拿到的原始数据,默认都是bytes;要当文本处理,必须用正确编码解码成str;反之,要写入二进制目标(如文件、socket),需将str编码为bytes。
encoding参数(推荐),避免依赖系统默认编码:with open("data.txt", "r", encoding="utf-8") as f:
encoding时,open()使用locale.getpreferredencoding(),Windows常为c
p936(GBK),Linux/macOS多为utf-8——跨平台隐患就在这里sys.stdin.encoding和sys.stdout.encoding可能不同,打印非ASCII字符前建议先确认乱码本质是“用错编码去解码字节”。例如Windows记事本保存的UTF-8文件若无BOM,用GBK打开就乱;反之Linux下用UTF-8读取GBK编码的文件也会出错。
UnicodeDecodeError?先用chardet或charset-normalizer探测编码:import charset_normalizer; print(charset_normalizer.from_path("file.txt"))
errors="ignore"或errors="replace"临时绕过(仅调试用):open("gbk.txt", "r", encoding="gbk", errors="replace")
utf-8-sig编码写入(自动加BOM)不依赖系统默认,统一用UTF-8,并显式声明。对必须兼容旧系统的场景(如读取Windows生成的ANSI文件),再单独处理。
encoding="utf-8",必要时用utf-8-sig兼容带BOM的文件csv模块时,open()仍需指定encoding;pandas读取用pd.read_csv(..., encoding="utf-8")
os.listdir()返回的已是str(Unicode),无需额外解码HTTP响应头中的Content-Type可能带charset,但实际内容编码未必一致;终端编码更易被忽略。
r = requests.get(url); r.encoding = "utf-8" 或直接用r.content.decode("utf-8")
import io; sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")
python script.py > out.txt),文件编码由Python控制