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 documented 做 bytes(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
我想将字节字符串的第一个字节连接到字符串的末尾:
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 documented 做 bytes(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