为什么read()输出的是字节而不是字符串?

5
我正在尝试分析一些二进制文件,并假设Python的read()函数从这篇文章和Tutorials Point的文章中返回一个字符串。然而,当我自己使用read()时,得到了与我所读内容不同的东西。
>>> with gzip.open('RTLog_20150424T194428.gz') as f:
       a = f.read(3)
       print(a)
       type(a)


b'use'
<class 'bytes'>
>>> a
b'use'
>>> str(a)
"b'use'"
>>> b = 'asdfasdfasdf'
>>> type(b)
<class 'str'>
>>> 

当我自己测试时,read()调用的输出返回了一个<class 'bytes'>对象,而不是一个<class 'str'>对象。我错在哪里了?
3个回答

8
您可以使用rbrt模式打开文件(默认为读取二进制数据,返回字节)。这在gzip.open的文档字符串中有提到:
引用: 模式参数可以是“r”,“rb”,“w”,“wb”,“x”,“xb”,“a”或“ab”来表示二进制模式,或者是“rt”,“wt”,“xt”或“at”来表示文本模式。默认模式是“rb”,默认压缩级别为9。
如果您在打开文件时传递关键字参数 mode="rt" (并且您知道正确的编码方式),则在调用 read 方法时应返回一个字符串。

好的,但是如果我读取一个二进制文件,这意味着我的输出是字节类型吗? - Dzhao
4
是的,就应该这样。你可能会被一些假定为Python 2的资源所迷惑,其中str是字节字符串类型。 - user2357112
您可以将任何文件作为字节或文本读取。是否会得到垃圾数据取决于文件中的内容。 - wim
@Dzhao 是的。如果字节序列不是您用于解码它们的字符编码的有效序列,则会失败并出现错误。这与任何其他数据格式没有区别,其中某些字节序列是无意义和/或无效的。 - dsh

7

您正在使用Python 3。 您链接到有关Python 2的信息。

文档指出:

如概述中所述,Python区分二进制和文本I / O。以二进制模式打开的文件(包括在模式参数中使用“b”)将内容作为字节对象返回,而不进行任何解码。在文本模式下(默认情况下,或者在模式参数中包含“t”时),文件的内容将作为str返回,这些字节首先使用平台相关的编码或使用指定的编码进行解码。

Python 3非常明确字节与字符(字符串)之间的区别。 Python 2则对此很懒散,这可能会导致许多问题。


-1
a = f.read()
str_data = a.decode("utf-8")

这对我有用,但我也是从 .txt 文件中读取而不是 .gz 文件 Python3


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接