Python struct.Struct.size返回意外值

Col*_*ett 7 python struct

我使用Python将一些文件转换为二进制格式,但我遇到了一个奇怪的陷阱.

问题

import struct
s = struct.Struct('Bffffff')
print s.size
Run Code Online (Sandbox Code Playgroud)

结果

28
Run Code Online (Sandbox Code Playgroud)

显然预期的大小是25,但它似乎将第一个byte(B)解释为某种类型的4字节整数.它还会写出一个4字节的整数而不是一个字节.

变通

存在一种解决方法,即将其分离B为单独的struct,如下所示:

import struct
s1 = struct.Struct('B')
s2 = struct.Struct('ffffff')
print s1.size + s2.size
Run Code Online (Sandbox Code Playgroud)

结果

25
Run Code Online (Sandbox Code Playgroud)

这种行为有什么解释吗?

Bha*_*Rao 6

来自文档

填充仅在连续的结构成员之间自动添加.在编码结构的开头或结尾没有添加填充.

如果你测试

>>> import struct
>>> s1 = struct.Struct('B')
>>> print s1.size
1
>>> s1 = struct.Struct('f')
>>> print s1.size
4
Run Code Online (Sandbox Code Playgroud)

因此,当你添加它是25...但反过来,B是1,其余的是4这样它将被填充,使它4因此答案是28 考虑这个例子

>>> s1 = struct.Struct('Bf')
>>> print s1.size
8
Run Code Online (Sandbox Code Playgroud)

在这里再次B1和填充3f4那么最终它出现于8其中的预期.

如上所述, 要覆盖它,您将不得不使用非本机方法

>>> s1 = struct.Struct('!Bf')
>>> print s1.size
5
Run Code Online (Sandbox Code Playgroud)

使用非原生大小和对齐时不添加填充,例如使用'<','>','='和'!'.


fal*_*tru 4

除非您为字节顺序、对齐方式指定任何字符,否则struct请使用本机字节顺序、对齐方式( @); 这会导致填充。

通过显式指定字节顺序,您可以获得您想要的:

>>> struct.Struct('!Bffffff').size  # network byte order
25
>>> struct.Struct('=Bffffff').size  # native byte order, no alignment.
25
>>> struct.Struct('>Bffffff').size  # big endian
25
>>> struct.Struct('<Bffffff').size  # little endian
25
>>> struct.Struct('@Bffffff').size  # native byte order, alignment. (+ native size)
28
Run Code Online (Sandbox Code Playgroud)