我试图使用' BQ'来解码字节对象。 Python 3.6.2上的格式(即unsigned char + unsigned long),长度应该是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
当我将格式说明符的顺序更改为&#39; QB&#39;时,它并不会抱怨长度,尽管它应该是相同的:
In [97]: struct.unpack('QB',bytesObj)
Out[97]: (35184770581765, 0)
但是当我更换B&#39; B&#39; for&#39; f&#39;,这应该增加3个字节所需的长度,但错误保持不变:
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
无论我之前使用过哪种格式,Q&#39;,总是会出现相同的错误,要求长度为16.只有当&#没有前面的格式时才会正常工作39; Q&#39;
我错过了什么吗?
答案 0 :(得分:1)
从9到16字节的跳转发生是因为Python添加了打包字节以确保结构中的元素在与C中相同的边界上对齐。
manual的第7.3节对此进行了解释。
q格式元素(long long)和Q格式元素(unsigned long long)被强制在8字节边界上对齐STARTING。在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所指出的,这个默认行为可以被覆盖;请参阅下面评论中的链接。