Python 2.6和3中的字节与字节数组

Python 2.6和3中的字节与字节数组,python,python-3.x,byte,bytearray,python-2.x,Python,Python 3.x,Byte,Bytearray,Python 2.x,我正在用Python 2.6中的bytesvsbytearray。我不明白为什么会有一些不同 bytes迭代器返回字符串: for i in bytes(b"hi"): print(type(i)) for i in bytes(b"hi"): print(type(i)) 给出: <type 'str'> <type 'str'> <type 'int'> <type 'int'> <class 'int'>

我正在用Python 2.6中的
bytes
vs
bytearray
。我不明白为什么会有一些不同

bytes
迭代器返回字符串:

for i in bytes(b"hi"):
    print(type(i))
for i in bytes(b"hi"):
    print(type(i))
给出:

<type 'str'>
<type 'str'>
<type 'int'>
<type 'int'>
<class 'int'>
<class 'int'>
给出:

<type 'str'>
<type 'str'>
<type 'int'>
<type 'int'>
<class 'int'>
<class 'int'>

为什么不同


我希望编写能够很好地转换为Python 3的代码。那么,Python3中的情况也一样吗?

我不确定是哪个版本,但是
bytes
实际上是一个
str
,如果您输入
类型(bytes(b“hi”)
->


bytearray
是一个可变字节数组,其中一个构造函数接受一个字符串。

在Python中,2.6字节仅仅是str的别名。
引入这种“伪类型”是为了[部分]准备程序[和程序员!]以便与Python 3.0转换/兼容,在Python 3.0中,str(系统上是unicode)和bytes(八位字节数组,用于存储数据,而不是文本)的语义和用法有严格的区别

类似地,字符串文字的b前缀在2.6中无效,但它在程序中是一个有用的标记,它明确标记程序员将字符串作为数据字符串而不是文本字符串的意图。当程序被移植到Py3k时,2to3转换器或类似的实用程序可以使用这些信息


您可能需要检查此项以获取更多信息。

我在Python 3.0上试用过它

在Python 3.0中,
bytes
迭代器返回
int
s,而不像Python 2.6那样返回字符串:

给出:

<type 'str'>
<type 'str'>
<type 'int'>
<type 'int'>
<class 'int'>
<class 'int'>

bytearray
迭代器还返回(至少)Python3.7的
class'int'
s.

字节
对象是单个字节的不可变序列

bytearray
对象是字节对象的可变对应项

就字节数而言,这几乎就是它与字节数之比。事实上,它们具有足够的灵活性,可以在操作中混合使用,而不会引发错误。事实上,在中有一整节专门介绍
字节
字节数组
API之间的相似性

从文档中可以找到一些关于原因的线索:

由于许多主要的二进制协议都基于ASCII文本编码,字节对象提供了几种方法,这些方法仅在处理ASCII兼容数据时有效,并且与字符串对象以各种其他方式密切相关

TL;DR

python2.6+
字节
=python2.6+
str
=python3.x
字节
!=python3.x
str

python2.6+
bytearray
=python3.x
bytearray

python2.x
unicode
=python3.x
str

长答案

自Python3.x以来,
bytes
str
在python中的含义发生了变化

首先简要回答您的问题,在python 2.6中,字节(b“hi”)
是一个不可变的字节数组(8位或八位字节)。因此每个
字节
的类型只是
字节
,这与Python2.6+中的
str
相同(但是,Python3.x中的情况并非如此)

bytearray(b“hi”)
也是一个可变字节数组。但当您询问其类型时,它是一个
int
,因为python将
bytearray
的每个元素表示为0-255范围内的整数(8位整数的所有可能值)。但是,
字节
数组的元素表示为该字节的ASCII值

例如,在<强> Python 2.6 +<强/> /P>中考虑

>>> 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
现在,Python3.x是一个完全不同的故事。正如您可能怀疑的那样,在python2.6+中,
str
literal意味着
byte
,这很奇怪。嗯

在Python3.x中,
str
是一个Unicode文本(以前只是一个字节数组,请注意Unicode和字节是两个完全不同的东西)
bytearray
是一个字节数组,而
bytes
是一个不可变的字节数组。它们的功能几乎相同。现在,如果我在Python3.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
在Python3.x中,
bytes
bytearray
是相同的东西,除了它们的可变性

你可能会问,
str
发生了什么str
被转换为Python2中的
unicode
,而
unicode
类型随后被从Python3中删除,因为它是多余的

我希望编写能够很好地转换为Python 3的代码。那么,Python3中的情况也一样吗

这取决于你想做什么。您是在处理字节还是在处理字节的ASCII表示

如果您处理的是字节,那么我的建议是在Python2中使用
bytearray
,这在Python3中是相同的。但如果这对你很重要,你就失去了不变性


如果您处理的是ASCII或文本,那么在Python2中将字符串表示为
u'hi'
,这在Python3中具有相同的含义<代码>'u'在Python2中有特殊的含义,它指示Python2将字符串文字视为
unicode
type在Python3中,u’没有任何意义,因为Python3中的所有字符串文本默认都是Unicode(在Python3中被混淆地称为
str
type,在Python2中被混淆地称为
Unicode
type)

有关更多信息,请参见:
bytes
对象仍然是不可变的,如
str
,而
bytearray
是可变的,并且具有类似于
列表的接口。