繁体   English   中英

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM