Python struct.pack 不一致

Python struct.pack is not consistent

我正在使用 struct.pack 来 return 我一个字节对象。然而,这是不一致的。

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 character chart,我就能明白为什么它变成了“5”和“!”在最后两个例子中,但它不应该 returned 我 b'\0x35\xfe\x01\x00' 和 b'\0x21\xfe\x01\x00' 而不是上面的结果?我在这里错过了什么?

我正在使用 Python 3.7.0.

不一致的不是包。让你困惑的是打印功能。

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

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

看看这个:

>>> 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 可以用 530x350o650b110101 表示。这是同一个 int 对象的所有数字文字。

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

打印出对象时,Python 在内部调用对象 str() 以确保对象可打印。对于 bytes 对象,这意味着将返回一个 bytes 字符串文字。由于有多种方式来表示该对象,Python 必须决定一种表示方式。

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

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

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

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