Python 2.7中的bytes类型和PEP-358

31 投票
3 回答
60296 浏览
提问于 2025-04-16 17:04

根据PEP 358的说明,bytes对象是用来存储一个可以改变的字节序列(范围是0到255),如果不是这样就会报错。

不过,我的Python 2.7却有不同的表现。

>>> bytes([1,2,3])
'[1, 2, 3]'
>>> bytes([280])
'[280]'
>>> bytes is str
True
>>> bytes
<type 'str'>

有没有人知道为什么这个PEP被声明为最终版本,但实际的实现却不符合呢?

3 个回答

4

bytes 对象实际上只在 Python 3.x 中存在。在 Python 2.7 中,bytesstr 的一个别名。这样做是为了帮助编写可以在 Python 2 和 3 之间通用的代码。

54

新的 bytes 类型 只在 3.x 版本 中存在。在 2.x 版本中,bytes 只是 str 类型的一个别名。也就是说,2.x 里并没有真正的新类型叫 bytes; 只是给 str 类型起了个新名字,并且有了新的表示方式。

这里有一段大家都喜欢的 文档摘录

Python 2.6 把 bytes 加入作为 str 类型的同义词,同时也支持 b'' 这种表示法。

2.6 版本的 str 和 3.0 版本的 bytes 类型有很多不同之处;最明显的是,它们的构造方式完全不同。在 3.0 中,bytes([65, 66, 67]) 会返回一个包含 3 个元素的结果,表示 ABC 的字节;而在 2.6 中,bytes([65, 66, 67]) 返回的是一个 12 字节的字符串,表示这个列表的 str()

在 2.6 中,bytes 主要用于测试对象类型,比如 isinstance(x, bytes)。这会帮助 2to3 转换器,因为它无法判断 2.x 代码中的字符串是打算包含字符还是 8 位字节;现在你可以使用 bytesstr 来准确表达你的意图,生成的代码在 Python 3.0 中也会是正确的。

40

bytes类型是在Python 3中引入的,但在PEP中讨论的是一种可变序列(bytes是不可变的),这种可变序列在Python 2.6中以bytearray的名字引入。

这个PEP显然没有按照说明实现(而且它确实提到被PEP 3137部分取代了),但我认为这只是名称的问题,并不是缺少功能。在Python 2中,bytes只是str的一个别名,目的是为了向后兼容,所以在这里并不重要。

下面是bytearray的使用示例:

>>> a = bytearray([1,2,3])
>>> a[0] = 5
>>> a
bytearray(b'\x05\x02\x03')

撰写回答