struct.calcsize(python)实际计算的是什么?

时间:2016-01-11 19:30:47

标签: python

关注the manual about struct.calcsize

truct.calcsize(fmt)¶

    Return the size of the struct (and hence of the string) corresponding to the given format

但我不明白为什么struct.calcsize('hll')不是struct.calcsize('h')加上两次struct.calcsize('l')。见下文。有什么想法吗?

In [216]: struct.calcsize('hll')
Out[216]: 24

In [217]: struct.calcsize('h')
Out[217]: 2

In [218]: struct.calcsize('l')
Out[218]: 8

2 个答案:

答案 0 :(得分:1)

我认为这是因为填充元素比机器字短,是为了提高效率。

访问作为机器字长的倍数的存储器地址(例如,64位机器的8个字节)往往更快。因此,C编译器将填充其结构,除非另有说明。 struct模块将在互操作性方面做同样的事情。

看起来它是可配置的,具体取决于您打算如何使用它。

答案 1 :(得分:0)

但还是很奇怪,如果我们改变元素的顺序,会得到不同的结果,例如:

In [187]: struct.calcsize('lhh')
Out[187]: 12

In [188]: struct.calcsize('hlh')
Out[188]: 18

In [189]: struct.calcsize('hhl')
Out[189]: 16

考虑到@Vlad 所说的,大小不应该都一样吗?

但是是的,这似乎与某些性能对齐和检查此示例有关:

In [195]: struct.calcsize('hlh')
Out[195]: 18

In [196]: struct.calcsize('llh')
Out[196]: 18

In [197]: struct.pack('hlh', 1, 2, 3)
Out[197]: b'\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00'

In [198]: struct.pack('llh', 1, 2, 3)
Out[198]: b'\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00'

可以看到,在short (h)旁边加上long,基本上是将short转换为long。

但这很令人困惑,因为理论上,我们应该能够做到以下几点:

In [199]: struct.unpack('hlh', b'\x01\x00\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00')

但实际上我们不能,python 抛出一个错误:

---------------------------------------------------------------------------
error                                     Traceback (most recent call last)
<ipython-input-199-41f8bd79fd25> in <module>
----> 1 struct.unpack('hlh', b'\x01\x00\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00')

error: unpack requires a buffer of 18 bytes