Python Struct模块行为异常
我在使用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 个回答
1
如果你使用的是64位的计算机架构,那么 int
类型占用4个字节,而 long
类型占用8个字节:
>>> struct.Struct('I').size
4
>>> struct.Struct('L').size
8
至于最后一个,这就是我们所说的“对齐”: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.
4
如果你查看一下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'))
7
对齐问题。
假设你在一个64位的非Windows平台上运行:Q和L的长度是8字节,I是4字节,H是2字节。
这些数据类型最好放在一个是它们大小的倍数的位置上,这样效率会更高。
因此,第二个结构体的排列方式是:
HH______ LLLLLLLL QQQQQQQQ
第三个结构体:
HH__IIII QQQQQQQQ
还有第四个结构体:
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