Python struct.Struct.size returns unexpected value

I use Python to convert some files to binary, but I came across an odd network.

Problem

the code

import struct s = struct.Struct('Bffffff') print s.size 

Result

 28 

Obviously, the expected size will be 25 , but it seems to interpret the first byte ( B ) as a 4-byte integer. It will also write out a 4 byte integer instead of a byte.

Work around

A workaround exists, namely splitting B out into a separate struct , for example:

the code

 import struct s1 = struct.Struct('B') s2 = struct.Struct('ffffff') print s1.size + s2.size 

Result

 25 

Are there any explanations for this behavior?

+7
python struct
source share
2 answers

If you do not specify any character for byte order, alignment, struct use your own byte order, alignment ( @ ); which cause filling.

By explicitly specifying the byte order, you can get what you want:

 >>> 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 
+4
source share

From docs

Filling is only automatically added between successive members of the structure. No additive is added at the beginning or end of the encoded structure.

If you test

 >>> import struct >>> s1 = struct.Struct('B') >>> print s1.size 1 >>> s1 = struct.Struct('f') >>> print s1.size 4 

So, when you add it, 25 ... But on the contrary, B is 1, and the rest 4 , so it will be complemented to make it 4 , so the answer is 28 Consider this example

 >>> s1 = struct.Struct('Bf') >>> print s1.size 8 

Here again, B is 1 , and padded 3 and f are 4 , so it reaches 8 , which is as expected.

As mentioned here , to override it, you will have to use non-native methods

 >>> s1 = struct.Struct('!Bf') >>> print s1.size 5 

No additive is added when using step size and alignment, for example. with '<,'>, '=, and' !.

+6
source share

All Articles