Python struct.unpack()要求具有特定格式模式的bytes对象具有错误的长度

Python struct.unpack()要求具有特定格式模式的bytes对象具有错误的长度,python,format,unpack,Python,Format,Unpack,我试图在Python 3.6.2上解码一个具有“BQ”格式(即无符号字符+无符号长)的bytes对象,其长度应为9个字节,但struct.unpack获取请求更多字节的错误: In [96]: struct.unpack('BQ',bytesObj) --------------------------------------------------------------------------- error Traceb

我试图在Python 3.6.2上解码一个具有“BQ”格式(即无符号字符+无符号长)的bytes对象,其长度应为9个字节,但
struct.unpack
获取请求更多字节的错误:

In [96]: struct.unpack('BQ',bytesObj)
---------------------------------------------------------------------------
error                                     Traceback (most recent call last)
<ipython-input-96-667267f631a1> in <module>()
----> 1 struct.unpack('BQ',bytesObj)

error: unpack requires a bytes object of length 16
但更奇怪的是,当我将“B”替换为“f”时,应该会将所需的长度增加3个字节,但错误保持不变:

In [97]: struct.unpack('QB',bytesObj)
Out[97]: (35184770581765, 0)
In [98]: struct.unpack('fQ',bytesObj)
---------------------------------------------------------------------------
error                                     Traceback (most recent call last)
<ipython-input-98-c3792c78fd43> in <module>()
----> 1 struct.unpack('fQ',bytesObj)

error: unpack requires a bytes object of length 16

In [99]: struct.unpack('Qf',bytesObj)
---------------------------------------------------------------------------
error                                     Traceback (most recent call last)
<ipython-input-99-78065617d606> in <module>()
----> 1 struct.unpack('Qf',bytesObj)

error: unpack requires a bytes object of length 12
[98]中的
:结构解包('fQ',bytesObj)
---------------------------------------------------------------------------
错误回溯(最近一次呼叫上次)
在()
---->1结构解包('fQ',bytesObj)
错误:解包需要长度为16的字节对象
在[99]中:结构解包('Qf',bytesObj)
---------------------------------------------------------------------------
错误回溯(最近一次呼叫上次)
在()
---->1结构解包('Qf',bytesObj)
错误:解包需要长度为12的字节对象
无论我在'Q'之前使用哪种格式,它总是得到相同的错误,要求长度为16。只有当“Q”没有前面的格式时,它才似乎工作得很好


我遗漏了什么吗?

从9字节跳到16字节是因为Python添加了打包字节,以确保结构中的元素与C中的元素在相同的边界上对齐

本手册第7.3节对此进行了解释

q格式元素(long-long)和q格式元素(unsigned long-long)强制从8字节边界开始对齐。在q/q之前的任何元素之后添加填充字节以确保这一点

运行以下代码将显示此操作:

from struct import *

print "QB: " + str(calcsize ('QB'))
bytesObj = pack('QB', 1, 2)
print unpack('QB', bytesObj)

print "BQ: " + str(calcsize ('BQ'))
bytesObj = pack('BQ', 1, 2)
print unpack('BQ', bytesObj)

print "qB: " + str(calcsize ('qB'))
bytesObj = pack('qB', 1, 2)
print unpack('qB', bytesObj)

print "Bq: " + str(calcsize ('Bq'))
bytesObj = pack('Bq', 1, 2)
print unpack('Bq', bytesObj)

print "Qf: " + str(calcsize ('Qf'))
bytesObj = pack('Qf', 1, 2.0)
print unpack('Qf', bytesObj)

print "fQ: " + str(calcsize ('fQ'))
bytesObj = pack('fQ', 1.0, 2)
print unpack('fQ', bytesObj)
这将提供以下输出:

QB: 9
(1, 2)
BQ: 16
(1, 2)
qB: 9
(1, 2)
Bq: 16
(1, 2)
Qf: 12
(1, 2.0)
fQ: 16
(1.0, 2)
希望这有帮助


(编辑):此外,正如OP所指出的,可以覆盖此默认行为;请参阅下面评论中的链接。

非常感谢!此外,特殊字符可用于禁用对齐过程: