Python 字节连接

Python bytes concatenation

我想将字节字符串的第一个字节连接到字符串的末尾:

a = b'\x14\xf6'
a += a[0]

我得到一个错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't concat bytes to int

当我输入 bytes(a[0]) 时,我得到:

b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

bytes({a[0]})给出了正确的b'\x14'

为什么我需要 {}

bytes 是序列类型。它的各个元素是整数。如果 a 是一个列表,您不能执行 a + a[0] 的原因与您不能执行 a + a[0] 的原因相同。您只能将一个序列与另一个序列连接起来。

bytes(a[0]) 给你,因为 a[0] 是一个整数,而 as documentedbytes(someInteger) 给你一个那么多零字节的序列(例如,bytes(3) 给你 3 个零字节)。

{a[0]}是一组。当您执行 bytes({a[0]}) 时,您将该集合的 contents 转换为字节对象。一般来说,这不是一个很好的方法,因为集合是无序的,所以如果你尝试用一个以上的字节来做,你可能得不到你期望的结果。

做您想做的最简单的方法是 a + a[:1]。你也可以做 a + bytes([a[0]])。创建单元素字节对象没有捷径;您必须使用切片或制作该字节的长度为一的序列。

字节不像字符串那样工作。当您使用单个值(而不是切片)进行索引时,您会得到一个整数,而不是长度为一的 bytes 实例。在您的情况下,a[0]20(十六进制 0x14)。

bytes 构造函数也会出现类似的问题。如果你传递一个整数作为参数(而不是一个可迭代对象),你会得到一个包含那么多空字节("\x00")的 bytes 实例。这解释了为什么 bytes(a[0]) 给你二十个空字节。带有大括号的版本有效,因为它创建了一个集合(可迭代)。

为了做你想做的事,我建议切片 a[0:1] 而不是使用单个值进行索引。这将为您提供一个 bytes 实例,您可以将其连接到现有值上。

a += a[0:1]

如果你想改变你的字节序列,你应该使用bytearray。它是可变的并且有 .append 方法:

>>> a = bytearray(b'\x14\xf6')
>>> a.append(a[0])
>>> a
bytearray(b'\x14\xf6\x14')

你的方法会发生什么:当你这样做时

a += a[0]

您正在尝试将整数添加到 bytes 对象。这没有意义,因为您正在尝试添加不同的类型。

如果你这样做

bytes(a[0])

你得到一个 bytes 长度为 20 的对象,正如 documentation 描述的那样:

If [the argument] is an integer, the array will have that size and will be initialized with null bytes.

如果您使用大括号,您将创建一个 set,并且在构造函数中选择了一个不同的选项:

If it is an iterable, it must be an iterable of integers in the range 0 <= x < 256, which are used as the initial contents of the array.

试试这个

values = [0x49, 0x7A]
concat = (values[0] << 8) + values[1]
print(hex(concat))

你应该得到 0x497A