代码之家  ›  专栏  ›  技术社区  ›  Craig McQueen Dr. Watson

python 2.6和3中的bytes与bytearray

  •  19
  • Craig McQueen Dr. Watson  · 技术社区  · 15 年前

    我正在试验 bytes VS bytearray 在Python 2.6中。我不明白有什么不同的原因。

    字节 迭代器返回字符串:

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

    给予:

    <type 'str'>
    <type 'str'>
    

    但一 字节射线 迭代器返回 int S:

    for i in bytearray(b"hi"):
        print(type(i))
    

    给予:

    <type 'int'>
    <type 'int'>
    

    为什么不同?

    我想写一些代码,可以很好地转换成python 3。那么,在python 3中情况是一样的吗?

    5 回复  |  直到 6 年前
        1
  •  25
  •   Community Michael Schmitz    7 年前

    在python中,2.6字节只是str的别名 .
    这种“伪类型”被引入[部分]准备程序[和程序员!]与python 3.0进行转换/兼容,其中对语义有严格的区分,并用于str(系统化的unicode)和bytes(是八位字节数组,用于存储数据,但不用于文本)

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

    你可以查一下这个 SO Question 更多信息。

        2
  •  5
  •   arshbot    6 年前

    对于(至少)python 3.7

    According to the docs:

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

    bytearray 对象是与字节对象相对应的可变对象。

    就目前而言 字节 VS 字节射线 . 事实上,他们 fairly interchangeable 并且设计得足够灵活,可以在不抛出错误的情况下混合操作。实际上,在 official documentation 致力于展示 字节 字节射线 API。

    从文件中可以找到一些线索:

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

        3
  •  3
  •   van    15 年前

    我不确定从哪个版本开始,但是 bytes 实际上是一个 str ,你可以看到 type(bytes(b"hi")) -gt; <type 'str'> .

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

        4
  •  3
  •   Craig McQueen Dr. Watson    15 年前

    我在python 3.0上试过。

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

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

    给予:

    <class 'int'>
    <class 'int'>
    

    bytearray 迭代器也返回 class 'int' S.

        5
  •  0
  •   meow    6 年前

    DR

    Python 2.6+ bytes = Python 2.6+ str = Python 3.x 字节 != Python 3.x 战略研究

    Python 2.6+ bytearray = Python 3.x 字节射线

    Python 2.x unicode = Python 3.x STR

    冗长的回答

    字节 STR 自从python 3.x以来,已经改变了python的含义。

    先回答你的问题 ,在Python 2.6中 bytes(b"hi") 是不可变的字节数组(8位或八位字节)。所以每种类型 byte 仅仅是 字节 ,与 STR 在python 2.6+中(然而,在python 3.x中不是这样)

    bytearray(b"hi") 也是一个可变的字节数组。但当你问它的类型时,它是一个 int ,因为python表示 字节射线 作为0-255范围内的整数(8位整数的所有可能值)。然而,一个元素 字节 数组表示为该字节的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是一个完全不同的故事。正如你可能怀疑的那样,奇怪的是为什么 STR 字面意思是 字节 在python2.6+中。嗯 this answer explains that

    在python 3.x中, STR 是一个Unicode文本(以前只是一个字节数组,请注意,Unicode和字节是两个完全不同的东西)。 字节射线 是一个 mutable 字节数组while 字节 是一个 不变的 字节数组。它们都有几乎相同的功能。现在,如果我在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中是相同的,除了易变性。

    发生了什么事 战略研究 你可能会问? STR 在python 3中转换成了什么 统一码 在python 2中,并且 统一码 类型随后从python 3中删除,因为它是多余的。

    我想写一些代码,可以很好地转换成python 3。那么,在python 3中情况是一样的吗?

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

    如果要处理字节 ,那么我的建议是 字节射线 在python 2中,与python 3中相同。但如果这对你很重要,你就失去了不变性。

    如果您处理的是ASCII或文本 ,然后将字符串表示为 u'hi' 在python 2中,它在python 3中具有相同的含义。 'u' 在python 2中有特殊的含义,它指示python 2将字符串文本视为 Unicode码 类型。在python 3中,u'没有任何意义,因为python 3中的所有字符串文字在默认情况下都是Unicode(这是一个令人困惑的调用 STR 输入python 3,然后 统一码 输入python 2)。