Python Struct模块表现很奇怪

时间:2012-01-30 17:39:41

标签: python

我正在使用struct模块,事情并没有像我预期的那样。由于我对模块的一些误解,我很确定。

import struct
s = struct.Struct('Q');
print s.size
s = struct.Struct('H L Q');
print s.size
s = struct.Struct('H I Q');
print s.size
s = struct.Struct('H I Q H');
print s.size

这个输出是:

8
24
16
18

我在这里缺少什么?为什么是第二种和第三种不同的尺寸,为什么是第四种 不是16?

4 个答案:

答案 0 :(得分:6)

对齐问题。

假设您在64位非Windows平台上运行:Q和L长度为8字节,I为4字节,H为2字节。

这些类型必须放在一个尺寸的倍数位置,以获得最佳效率。

因此,第二个结构将排列为:

HH______ LLLLLLLL QQQQQQQQ

第三结构:

HH__IIII QQQQQQQQ

和第4个结构:

HH__IIII QQQQQQQQ HH

如果您不想要对齐,并且要求L有4个字节(“标准”大小),则需要使用=><格式,如http://docs.python.org/library/struct.html#struct-alignment

中所述
import struct
s = struct.Struct('=Q')
print s.size
s = struct.Struct('=HLQ')
print s.size
s = struct.Struct('=HIQ')
print s.size
s = struct.Struct('=HIQH')
print s.size

演示:http://ideone.com/EMlgm

答案 1 :(得分:3)

如果你看the documentation of struct

  

或者,格式字符串的第一个字符可用于指示打包数据的字节顺序,大小和对齐方式,如下表所示:

Character Byte order             Size       Alignment
@         native                 native     native
=         native                 standard   none
<         little-endian          standard   none
>         big-endian             standard   none
!         network (= big-endian) standard   none
  

如果第一个字符不是其中之一,则假定为“@”。

由于您未提供任何尺寸提示,因此选择native尺寸和对齐方式,由于对齐和不同尺寸,因此可能会产生不可预测的尺寸。这应该可以解决问题:

import struct
print(struct.calcsize('!Q'))
print(struct.calcsize('!H L Q'))
print(struct.calcsize('!H I Q'))
print(struct.calcsize('!H I Q H'))

答案 2 :(得分:0)

如果您使用64位架构,则int为4个字节,long为8个字节:

>>> struct.Struct('I').size
4
>>> struct.Struct('L').size
8

对于最后一个,这就是我们所说的&#34;对齐&#34;:http://docs.python.org/library/struct.html#struct-alignment

>>> struct.Struct('I').size
4
>>> struct.Struct('H').size
2
>>> struct.Struct('HI').size
8
# => aligned to the next word.

答案 3 :(得分:0)

它与对齐有关。如果您将一个字节顺序字符添加到格式中,您将得到您期望的答案。

来源:http://docs.python.org/library/struct.html