0

我正在使用 struct.pack 向我返回一个字节对象。但是,它是不一致的。

print(struct.pack('BbbB', 0x1B, -2, 1, 0)) #returns b'\x1b\xfe\x01\x00' GOOD
print(struct.pack('BbbB', 0x0F, -2, 1, 0)) #returns b'\x0f\xfe\x01\x00' GOOD
print(struct.pack('BbbB', 0x0C, -2, 1, 0)) #returns b'\x0c\xfe\x01\x00' GOOD
print(struct.pack('BbbB', 0x35, -2, 1, 0)) #returns b'5\xfe\x01\x00'    ???
print(struct.pack('BbbB', 0x21, -2, 1, 0)) #returns b'!\xfe\x01\x00'    ???

如果我看一下ASCII 字符表,我可以明白为什么它变成了“5”和“!” 在最后两个示例中,但它不应该返回我 b' \0x35 \xfe\x01\x00' 和 b' \0x21 \xfe\x01\x00' 而不是上面的结果吗?我在这里想念什么?

我正在使用 Python 3.7.0。

4

2 回答 2

2

看看这个:

>>> b'\x35\xfe\x01\x00'
b'5\xfe\x01\x00'
>>> b'\x35\xfe\x01\x00' == b'5\xfe\x01\x00'
True
>>> b'\x35'
b'5'
>>> b'\x35' == b'5'
True
>>> b'\x35'[0]
53
>>> b'5'[0]
53

两者都b'\x35'具有b'5'相同的字节值 0x35。只是它们都是相同值的两种不同表示

有多种方法可以为相同的实际值写入文字值是很常见的。例如,十进制值 53 可以用530x350o65或表示0b110101。那是同一个int对象的所有数字文字。

就像那样,b'\x35只是b'5'同一个字节对象的两个字节串文字。

当您打印出对象时,Pythonstr()在内部调用对象以确保对象是可打印的。对于字节对象,这意味着正在返回字节字符串文字。由于有多种方法可以表示该对象,Python 必须决定一种表示。

对于字节,规则很简单,只要一个字节可以表示为可打印的 ASCII 字符,就使用该字符而不是转义序列。这通常允许您读取表示 ASCII 数据的字节字符串。例如b'foo',比b'\x66\x6f\x6f'(但意思相同)更具可读性。

如果您需要获得字节对象的一致字符串表示,您可以做的是将其显式转换为十六进制字符串。例如通过调用bytes.hex

>>> b'5\xfe\x01\x00'.hex()
'35fe0100'

当然,现在这不再是二进制数据,而是表示二进制数据的字符串,编码为十六进制字符串。如果您想实际传输数据,例如通过网络或文件内部,您将希望将其保留为bytes对象并使用它。

于 2018-08-09T08:35:14.403 回答
1

不一致的不是包装。让您感到困惑的是打印功能。

两个都 '!' (ascii value 33, hexadecimal 0x21) 和 '5' (ascii value 53, hexadecimal 0x35) 是可打印字符,所以它们只是正常打印。但是其他字节是不可打印的,所以 python 求助于打印它们的十六进制表示,这样你至少可以看到一些有意义的东西。

字节值是您期望的值,不用担心。

于 2018-08-09T08:27:03.663 回答