必须用"rb"模式打开二进制文件才能确保read()返回bytes;文本模式会尝试解码,易抛UnicodeDecodeError,尤其Windows下处理图片/PDF时;后续操作决定是否解码:文本处理需.decode(),哈希/图像等应保持bytes。

open() 用 "rb" 模式才能保证 read() 返回 bytes
默认 open() 是文本模式,哪怕你没写 "r",它也会尝试用系统默认编码(比如 UTF-8)解码文件内容,一旦遇到无法解码的字节,就直接抛 UnicodeDecodeError。想拿到原始字节?必须显式指定二进制模式。
-
open("data.bin", "rb")→read()返回bytes,安全、确定、无解码 -
open("data.bin", "r")或open("data.bin")→ 即使文件是二进制,也会尝试解码,大概率报错 - Windows 上打开非文本文件(如图片、PDF)时尤其容易翻车,因为换行符和 BOM 处理逻辑会干扰原始字节流
读取后要不要解码,取决于你接下来要干什么
不是“读完就要解码”,也不是“永远不许解码”。关键看下游操作:处理文本内容(比如解析 JSON、读取 CSV)才需要解码;做哈希、加密、网络传输、图像像素操作,就该全程保持 bytes。
- 解码要用
.decode(encoding="utf-8"),不能直接用str(...)—— 后者只是调用对象的__str__,对bytes来说返回的是带b'...'的可读字符串,不是真正的文本 - 如果不确定编码,别硬试
utf-8;可用chardet.detect()先猜,或用errors="ignore"/errors="replace"防崩,但会丢信息 -
bytes对象没有.splitlines()这种方法,得先解码成str,或者用.split(b"\n")(注意是b"\n",不是"\n")
read() 和 readline() 在二进制模式下的行为差异
二进制模式下,read() 返回 bytes 没问题,但 readline()、for line in f: 也返回 bytes —— 只是它们按 b"\n" 切分,不是按 Unicode 换行符。这点常被忽略,导致误以为“读行”能自动处理编码。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
-
f.readline()在"rb"模式下返回bytes,结尾含b"\n"(如果有),不会帮你去掉或转换 -
for line in f:在二进制模式下,每次迭代也是bytes,且只认b"\n",不认b"\r\n"或b"\r"为行结束(除非你自己处理) - 想按文本逻辑读行又保留原始字节?不如一次性
read()全部再用.splitlines(keepends=True),更可控
常见错误:把 bytes 当 str 直接拼接或格式化
比如 b"hello" + "world" 会报 TypeError: can't concat bytes to str;f"prefix{data}" 中 data 是 bytes 也会崩。这不是语法问题,是类型契约没守牢。
立即学习“Python免费学习笔记(深入)”;
- 拼接前统一类型:
b"hello" + b"world"或"hello".encode() + "world".encode() - 格式化时,若需嵌入
bytes,用!r或先转十六进制:f"data: {data!r}"或f"{data.hex()}" - 写入文件时也得匹配:用
"wb"才能写bytes,用"w"写bytes会报错,反过来用"wb"写str也会报错
bytes 去当 str 用”。

















