Python struct.Struct.size 返回意外值
Python struct.Struct.size returning unexpected value
我正在使用 Python 将一些文件转换为二进制格式,但我 运行 变成了一个奇怪的圈套。
问题
代码
import struct
s = struct.Struct('Bffffff')
print s.size
结果
28
显然预期的大小是 25
,但它似乎将第一个字节 (B
) 解释为某种 4 字节整数。它还将写出一个 4 字节整数而不是一个字节。
解决方法
存在变通方法,即将 B
分离成单独的 struct
,如下所示:
代码
import struct
s1 = struct.Struct('B')
s2 = struct.Struct('ffffff')
print s1.size + s2.size
结果
25
对这种行为有什么解释吗?
来自docs
Padding is only automatically added between successive structure members. No padding is added at the beginning or the end of the encoded struct.
如果你测试
>>> import struct
>>> s1 = struct.Struct('B')
>>> print s1.size
1
>>> s1 = struct.Struct('f')
>>> print s1.size
4
所以当你添加它时它是 25
...但是反过来,B
是 1 其余的是 4
所以它会被填充以使其 4
因此答案是 28
考虑这个例子
>>> s1 = struct.Struct('Bf')
>>> print s1.size
8
同样这里 B
是 1
并填充 3
和 f
是 4
所以最后它得出 8
这是不出所料。
如前所述here要覆盖它,您将不得不使用非本机方法
>>> s1 = struct.Struct('!Bf')
>>> print s1.size
5
No padding is added when using non-native size and alignment, e.g. with ‘<’, ‘>’, ‘=’, and ‘!’.
除非您为字节顺序、对齐方式指定任何字符,否则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
我正在使用 Python 将一些文件转换为二进制格式,但我 运行 变成了一个奇怪的圈套。
问题
代码
import struct
s = struct.Struct('Bffffff')
print s.size
结果
28
显然预期的大小是 25
,但它似乎将第一个字节 (B
) 解释为某种 4 字节整数。它还将写出一个 4 字节整数而不是一个字节。
解决方法
存在变通方法,即将 B
分离成单独的 struct
,如下所示:
代码
import struct
s1 = struct.Struct('B')
s2 = struct.Struct('ffffff')
print s1.size + s2.size
结果
25
对这种行为有什么解释吗?
来自docs
Padding is only automatically added between successive structure members. No padding is added at the beginning or the end of the encoded struct.
如果你测试
>>> import struct
>>> s1 = struct.Struct('B')
>>> print s1.size
1
>>> s1 = struct.Struct('f')
>>> print s1.size
4
所以当你添加它时它是 25
...但是反过来,B
是 1 其余的是 4
所以它会被填充以使其 4
因此答案是 28
考虑这个例子
>>> s1 = struct.Struct('Bf')
>>> print s1.size
8
同样这里 B
是 1
并填充 3
和 f
是 4
所以最后它得出 8
这是不出所料。
如前所述here要覆盖它,您将不得不使用非本机方法
>>> s1 = struct.Struct('!Bf')
>>> print s1.size
5
No padding is added when using non-native size and alignment, e.g. with ‘<’, ‘>’, ‘=’, and ‘!’.
除非您为字节顺序、对齐方式指定任何字符,否则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