Python 3 的 str 是 Unicode 文本,bytes 是字节;Python 2 的 str 是字节串,需 decode 才得 unicode。二者语义分离,不可隐式转换,文件操作须显式指定 encoding 或用 bytes 模式。

Python 3 中字符串默认是 str 类型,底层直接以 Unicode 存储,不是“用了 Unicode 编码”,而是“本身就是 Unicode 字符序列”;Python 2 的 str 默认是字节序列(ASCII),必须显式用 u"中文" 才能拿到 Unicode——这是根本性设计差异,不是配置能改的。
Python 2 的 str 是字节,不是文本
Python 2 的 str 类型本质是字节串(bytes),它不携带编码信息。当你写 s = "中文",Python 2 实际存的是文件保存时的原始字节(比如 UTF-8 编码的 \xe4\xb8\xad\xe6\x96\x87),但解释器不认为它是“中文”,只当它是几个无意义的字节。
- 如果源文件声明了
# -*- coding: utf-8 -*-,"中文"能被读入,但仍是str(即 UTF-8 字节) - 想真正当文本处理?必须手动
"中文".decode('utf-8')得到unicode对象 - 打印、拼接、正则匹配前若漏掉
.decode(),极易触发UnicodeDecodeError
Python 3 的 str 是 Unicode 文本,bytes 才是字节
Python 3 彻底分离语义:str 表示人类可读的文本(内部统一用 Unicode 码点),bytes 表示机器可读的原始字节。二者不能隐式互转,也不能混用。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
-
s = "中文"→s是str,值为 Unicode 字符 U+4E2D U+6587,和源文件编码无关 - 要写入文件或发网络请求?必须显式
s.encode('utf-8')得到bytes - 从文件读取二进制内容?得到的是
bytes,需b.decode('gbk')才能变str(解码方式取决于数据真实编码) - 错误示例:
"abc" + b"def"→TypeError: can't concatenate str and bytes
常见错误场景:读文件时的编码错位
最典型的问题不是“为什么乱码”,而是“为什么有时对、有时错”。根源在于:Python 3 的 open() 默认用系统 locale 解码,而 locale 不一定等于文件实际编码。
立即学习“Python免费学习笔记(深入)”;
- Linux/macOS 下
locale.getpreferredencoding()通常是UTF-8,读 UTF-8 文件没问题 - Windows 中文系统下 locale 常是
GBK,读 UTF-8 文件就会报UnicodeDecodeError - 正确做法永远显式指定:
open("data.txt", encoding="utf-8")或open("data.txt", "rb")(返回bytes,再按需解码) - 别依赖
sys.getdefaultencoding()——它只控制 str/bytes 之间隐式转换(Python 3 中已禁用),和文件 I/O 无关
真正的复杂点不在“怎么写”,而在“怎么判断数据的真实编码”。bytes 没有自我描述能力,b'\xe4\xb8\xad' 可能是 UTF-8 的“中”,也可能是 GBK 的“涓”,只能靠上下文或探测库(如 chardet)猜。一旦猜错,后续所有 .decode() 都是徒劳——这个环节没有银弹,只能前置约束或人工确认。

















