Python struct模块无法正确处理无符号短整型0xf031问题求助
问题分析与解决方案
你的核心问题有两个:Python对bytes对象的显示逻辑误解,以及字节序和字节拆分顺序的混淆。
1. 为什么看起来输出不符合预期?
Python在显示bytes对象时,会将可打印的ASCII字符(如0x31对应字符'1')直接显示为字符,而非十六进制转义序列。你看到的b'1\xf0\x18\x00'和你预期的b'\x31\xf0\x18\x00'是完全相同的字节序列,只是显示方式不同。可以通过以下代码验证:
actual = b'1\xf0\x18\x00' expected = b'\x31\xf0\x18\x00' print(actual == expected) # 输出: True
如果想查看原始的十六进制字节,避免显示混淆,可以使用binascii.hexlify:
import binascii print(binascii.hexlify(b'1\xf0\x18\x00')) # 输出: b'31f01800'
2. 关于struct.pack的字节序
你使用的<格式符表示小端序(低字节在前,高字节在后)。对于数值61489(即0xf031),小端序的字节排列就是0x31(低字节)在前,0xf0(高字节)在后,这和你预期的字节顺序是一致的——只是Python把0x31显示成了'1'。
如果你的串口协议要求的是大端序(高字节在前,低字节在后),则需要使用>格式符:
from struct import pack d1 = 61489 d2 = 24 print(pack('>HH', d1, d2)) # 输出: b'\xf01\x00\x18',对应十六进制f0310018
3. 拆分字节时的顺序错误
你拆分十六进制字符串时,把高字节和低字节的顺序搞反了。hex(61489)得到的是'0xf031',其中0x31是低字节,0xf0是高字节。小端序要求先打包低字节,再打包高字节,正确的写法应该是:
d1_hex = hex(61489) # '0xf031' # 低字节是最后两位31,高字节是前两位f0 low_byte = int(d1_hex[4:], 16) # 0x31 high_byte = int(d1_hex[2:4], 16) # 0xf0 print(pack('<BBH', low_byte, high_byte, 24)) # 输出: b'1\xf0\x18\x00',即你预期的字节序列
总结
- 不要被Python的
bytes显示方式迷惑,可打印ASCII字符会直接显示为字符,本质字节和十六进制转义是一致的。 - 确认你的串口协议要求的字节序(小端/大端),对应使用
struct.pack的格式符<或>。 - 拆分多字节数值时,明确低字节和高字节的顺序,再对应传入
pack函数。
内容的提问来源于stack exchange,提问作者KarlNorway
相关产品推荐
相关产品推荐

