【问题标题】:bytes vs bytearray in Python 2.6 and 3Python 2.6 和 3 中的字节与字节数组
【发布时间】:2010-12-16 23:25:57
【问题描述】:

我正在 Python 2.6 中尝试使用 bytesbytearray。我不明白一些差异的原因。

bytes 迭代器返回字符串:

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

给予:

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

但是bytearray 迭代器返回ints:

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

给予:

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

为什么不一样?

我想编写可以很好地转换为 Python 3 的代码。那么,Python 3 中的情况是否相同?

【问题讨论】:

    标签: python python-3.x byte bytearray python-2.x


    【解决方案1】:

    我不确定是从哪个版本开始的,但是bytes实际上是一个str,如果你这样做可以看到type(bytes(b"hi")) -> &lt;type 'str'&gt;

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

    【讨论】:

      【解决方案2】:

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

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

      您可能需要查看此SO Question 以获取更多信息。

      【讨论】:

      【解决方案3】:

      我在 Python 3.0 上尝试过。

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

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

      给予:

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

      bytearray 迭代器也返回 class 'int's。

      【讨论】:

      • 但是,bytes 对象仍然是不可变的,就像str,而bytearray 是可变的并且具有类似list 的接口。
      【解决方案4】:

      对于(至少)Python 3.7

      According to the docs:

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

      bytearray 对象是字节对象的可变对应物。

      bytesbytearray 而言,差不多就是这样。事实上,它们是fairly interchangeable 并且设计得足够灵活,可以在操作中混合而不会引发错误。事实上,official documentation 中有一整节专门展示了bytesbytearray api 之间的相似之处。

      文档中有关原因的一些线索:

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

      【讨论】:

        【解决方案5】:

        TL;DR

        python2.6+ bytes = python2.6+ str = python3.x bytes != python3.x str

        python2.6+ bytearray = python3.x bytearray

        python2.x unicode = python3.x str

        长答案

        bytesstr 自 python 3.x 以来在 python 中的含义发生了变化。

        首先回答您的问题,在 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 是一个完全不同的故事。正如您可能已经猜到的那样,为什么str 文字在 python2.6+ 中意味着 byte 很奇怪。嗯this answer explains that

        在 Python 3.x 中,str 是一个 Unicode 文本(以前只是一个字节数组,请注意 Unicode 和字节是两个完全不同的东西)。 bytearraymutable 字节数组,而 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
        

        bytesbytearray 在 python 3.x 中是相同的东西,除了可变性。

        你可能会问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 类型。 'u' 在 python 3 中没有意义,因为默认情况下 Python 3 中的所有字符串文字都是 Unicode(在 python 3 中被混淆地称为 str 类型,在 python 2 中称为 unicode 类型)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-11-25
          • 1970-01-01
          • 1970-01-01
          • 2018-03-02
          • 1970-01-01
          • 2011-11-14
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多