Python 3中file.read(x)读取字符而非字节?是Bug还是认知遗漏?
这不是Bug,是Python 3的文件处理设计差异!
这可不是什么bug哦,是Python 3和Python 2在文件IO上的核心区别之一,很多刚从Python 2转过来的同学都会碰到这个问题~
核心原因:默认打开模式的变化
- Python 2中,
open()默认以文本模式打开,但返回的是字节串(str类型本质是字节),所以read(1)读取的是1个字节。 - Python 3中,
open()默认同样是文本模式,但返回的是Unicode字符串(str类型),这时候read(1)读取的是1个Unicode字符,不管这个字符在UTF-8编码下占2-4个字节。
两种模式的read参数差异
你查看的文档是io.RawIOBase.read,这个类是二进制IO的基类,对应的是Python 3里用二进制模式('rb')打开的文件对象。而默认文本模式下的文件对象是TextIOWrapper,它的read(n)参数是字符数,不是字节数——这是Python 3为了更友好处理Unicode特意做的设计调整。
如何复刻Python 2的字节读取行为?
如果需要按字节读取内容,只要用二进制模式打开文件就行:
with open('your_file.txt', 'rb') as f: byte_data = f.read(1) # 这里返回的是1字节的bytes对象,和Python 2行为完全一致
举个实际例子:假设文件里有一个UTF-8编码的中文“好”(占3字节)
- 文本模式下
read(1)→ 返回'好'(1个完整的Unicode字符) - 二进制模式下
read(1)→ 返回b'\xe5'(这个字符的第一个字节)
所以本质上是你混淆了文本模式和二进制模式的read方法参数含义,这完全是Python 3的正常设计,不是bug哦~
内容的提问来源于stack exchange,提问作者Kostya
相关产品推荐
相关产品推荐

