Python struct.pack不一致

时间:2018-08-09 08:17:13

标签: python byte python-3.7 struct.pack

我正在使用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 character chart,我会明白为什么它变成“ 5”和“!”在最后两个示例中,但不应该返回b' \ 0x35 \ xfe \ x01 \ x00'和b' \ 0x21 \ xfe \ x01 \ x00'以上结果?我在这里想念什么?

我正在使用Python 3.7.0。

2 个答案:

答案 0 :(得分: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可以用530x350o650b110101表示。这就是同一个int对象的所有数字文字。

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

打印出对象时,Python内部调用对象上的str()以确保对象可打印。对于bytes对象,这意味着将返回字节字符串文字。而且由于有多种表示该对象的方法,因此Python必须决定一种表示形式。

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

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

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

当然,现在这不再是二进制数据,而是表示为二进制数据的 string ,已编码为十六进制字符串。如果要实际传输数据(例如,通过网络或文件内部),则需要将其保留为bytes对象,然后使用它即可。

答案 1 :(得分:1)

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

都是'!' (ASCII值33,十六进制0x21)和'5'(ASCII值53,十六进制0x35)是可打印的字符,因此它们只是正常打印。但是其他字节不可打印,因此python会打印其十六进制表示形式,以便您至少可以看到有意义的

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