[英]struct.unpack() requires wrong length from bytes object with specific format pattern
我正在尝试在Python 3.6.2上以'BQ'格式(即,无符号字符+无符号长)解码一个字节对象,该长度应该为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
当我将格式说明符的顺序更改为“ QB”时,它不会抱怨长度,尽管应该是相同的:
In [97]: struct.unpack('QB',bytesObj)
Out[97]: (35184770581765, 0)
但是当我将'B'替换为'f'时,它变得更加陌生,这应该将所需的长度增加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”之前使用哪种格式,它总是会遇到相同的错误,要求长度为16。似乎只有在没有“ Q”的格式时,它才能正常工作。
我想念什么吗?
从9字节跳到16字节是因为Python添加了打包字节,以确保结构中的元素与C中的边界对齐。
手册第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所指出的,此默认行为可以被覆盖。 请参阅下面评论中的链接。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.