Python 2.6和3中的bytes与bytearray
我正在尝试了解在Python 2.6中,bytes
和bytearray
之间的区别,但有些地方我不太明白。
当我用bytes
来遍历时,它会返回字符串:
for i in bytes(b"hi"):
print(type(i))
结果是:
<type 'str'>
<type 'str'>
但是当我用bytearray
来遍历时,它会返回int
类型的数字:
for i in bytearray(b"hi"):
print(type(i))
结果是:
<type 'int'>
<type 'int'>
为什么会有这样的区别呢?
我想写一些代码,能够顺利迁移到Python 3。那么在Python 3中情况也是这样吗?
5 个回答
简而言之
在python2.6及以上版本中,
bytes
和str
是一样的,等于python3.x中的bytes
,但不等于python3.x中的str
。python2.6及以上版本中的
bytearray
和 python3.x中的bytearray
是一样的。python2.x中的
unicode
和 python3.x中的str
是一样的。
详细解答
在python 3.x中,bytes
和 str
的含义发生了变化。
简单回答你的问题,在python 2.6中,bytes(b"hi")
是一个不可变的字节数组(每个字节8位)。所以每个byte
的类型就是byte
,这和python 2.6及以上版本中的str
是一样的(但在python 3.x中就不是这样了)。
bytearray(b"hi")
是一个可变的字节数组。当你查看它的类型时,它是int
,因为python把bytearray
中的每个元素表示为0到255之间的整数(这是8位整数的所有可能值)。而bytes
数组中的元素则表示为该字节的ASCII值。
例如,在Python 2.6+中:
>>> barr=bytearray(b'hi')
>>> bs=bytes(b'hi')
>>> barr[0] # python shows you an int value for the 8 bits 0110 1000
104
>>> bs[0] # python shows you an ASCII value for the 8 bits 0110 1000
'h'
>>> chr(barr[0]) # chr converts 104 to its corresponding ASCII value
'h'
>>> bs[0]==chr(barr[0]) # python compares ASCII value of 1st byte of bs and ASCII value of integer represented by first byte of barr
True
现在,python 3.x的情况完全不同。你可能会觉得奇怪,为什么在python2.6+中str
字面量会表示为byte
。好吧,这个回答解释了这个问题。
在Python 3.x中,str
是Unicode文本(之前只是字节数组,注意Unicode和字节是完全不同的东西)。bytearray
是一个可变字节数组,而bytes
是一个不可变字节数组。它们几乎有相同的功能。现在如果我在python 3.x中再次运行上面的代码,结果如下。在Python 3.x中:
>>> barr=bytearray(b'hi')
>>> bs=bytes(b'hi')
>>> barr[0]
104
>>> bs[0]
104
>>> bs[0]==barr[0] # bytes and bytearray are same thing in python 3.x
True
在python 3.x中,bytes
和 bytearray
是相同的,除了可变性。
你可能会问str
发生了什么?在python 3中,str
被转换成了python 2中的unicode
,而unicode
类型随后在python 3中被移除,因为它是多余的。
我想写一些代码,能够很好地转换到Python 3中。那么在Python 3中的情况是一样的吗?
这要看你想做什么。你是在处理字节,还是在处理字节的ASCII表示?
如果你在处理字节,那么我的建议是在Python 2中使用bytearray
,它在python 3中是一样的。但如果这对你来说重要的话,你会失去不可变性。
如果你在处理ASCII或文本,那么在Python 2中将你的字符串表示为u'hi'
,在python 3中有相同的含义。'u'
在Python 2中有特殊含义,指示python 2将字符串字面量视为unicode
类型。在python 3中,'u'没有任何意义,因为在python 3中所有字符串字面量默认都是Unicode(这在python 3中被混淆地称为str
类型,而在python 2中称为unicode
类型)。
在Python 2.6中,bytes只是str的一个别名。
这个“伪类型”是为了让程序和程序员提前做好准备,以便将来能更好地适应Python 3.0。在Python 3.0中,str和bytes有严格的区别:str是用来处理文本的(它们是系统性地使用unicode),而bytes则是用来存储数据的(它们是字节数组,不适合用来处理文本)。
同样,在2.6版本中,字符串前面的b前缀并没有实际效果,但它在程序中是一个有用的标记,明确表示程序员希望这个字符串作为数据字符串,而不是文本字符串。这些信息可以在程序迁移到Python 3时,被2to3转换器或类似工具使用。
你可以查看这个SO问题以获取更多信息。