In C programming, a structure (struct
) creates a type that can group items of possibly different types into one type. The Python struct module facilitates conversions between Python values and C structs represented as Python bytes objects.
About the Function
The struct.pack() converts a list of values into corresponding string types. The user should specify both the format and order of the values that should be converted.
Function Syntax and Parameters
struct.pack(format, d1, d2, ...)
The first parameter of the function represents the format string. A format string specifies how the data should be packed and unpacked.
Format Characters
Here are some of the common format characters.
- ‘c’ – character
- ‘s’ – char[]
- ‘i’ – integer
- ‘f’ – float
- ‘?’ – boolean
- ‘q’ – long long integer
The data to be packed is represented by the rest of the arguments(d1, d1, d(n)…).
Returns
The function returns a Python string type consisting of the packed data in the specified format.
Importing the Module
As of the latest Python 3.10, this module is available in the Python Standard Library under the Binary Data Services category. Make sure to implement these programs on your own. Try our Online Python Interpreter.
import struct
Simple Program to Pack Data
Here is a code example illustrating how to pack data into its binary form using struct pack.
import struct
packedData = struct.pack('i 4s f', 10, b'Code', 2022)
print(packedData)
Output
b'\n\x00\x00\x00Code\x00\xc0\xfcD'
Other struct Functions to Learn
Alongside the struct pack, there are other functions within the module you should know.
struct.unpack()
Strings of binary representation are converted into their original form using this function. The return of struct.unpack()
is always a tuple.
import struct
packedData = b'\n\x00\x00\x00PythonPool\x00@\x1cE'
unpackedData = struct.unpack('i 4s f', packed)
print(unpackedData)
Output
(10, b'PythonPool', 2500.0)
struct.calcsize()
This function calculates the size of the String representation of struct. Given that you have provided a format string.
import struct
structSize = struct.calcsize('i 4s f')
print("Size in bytes: {}".format(structSize))
Output
Size in bytes: 12
struct.pack() Big Endian & Little Endian Explained
The terms Big Endian and Little Endian represent the byte order based on the host system. For example, Intel x86 and AMD64 (x86-64) are little-endian processors. Motorola 68000 and PowerPC G5 are considered big-endian. There’s another category that acts as both types called bi-endian. ARM and Intel Itanium are examples of bi-endian. You can use sys.byteorder()
to check the endianness of your own system processor.
struct.pack() in Python 2 vs Python 3
In Python 2, struct.pack() always returned a string type. It is in Python 3 that the function, in certain cases, will return a bytes object. Due to a lack of support of byte objects with this function in Python 2, it considered both bytes and string to be the same when returning.
Packing/Unpacking Float using struct.pack()
If you’re packing Python float values as binary using .pack(), you should keep in mind that the C language calls Python floats as a double. If you pass the values in as a float, you will lose your values accuracy after packing. This is because C floats are less accurate than Python floats.
import struct
f = open('file.bin', 'wb')
value = 1.23456
data = struct.pack('f',value)
Printing this data would result in 1.2345600128173828
Instead of,
data = struct.pack('f',value)
Do this.
data = struct.pack('d',value)
Packing binary floats as doubles ensure that .pack() keeps the data’s integrity after packing or unpacking processes. Failing to do so may result in inaccurate data in the long run.
struct.pack() vs struct.pack_into()
struct.pack() | struct.pack_into() |
---|---|
Requires a format along with the values. | Requires a buffer and an offset along with the values. It can be created using the ctype module. |
Simply returns the packed data | Packs the provided data into the buffer |
Returns a string type | Do not return anything. |
Common Errors in struct.pack()
struct.pack() Argument Out of Range
Let’s look at the following code:
data_length=30
code=202
data=[51400,31400,100,51400,31400,100,51400,31400,100]
for i in struct.pack('<2B%dh' % len(data), *total_data[3:len(total_data)]):
checksum = checksum ^ ord(i)
Error Output
struct.error: short format requires SHRT_MIN <= number <= SHRT_MAX
The list data has the highest value of 51400. However, signed short (h) has a max value of 32768. A perfect solution is to provide an unsigned short (H) with a max value of 65535.
FAQs on Python struct pack
struct.iter_unpack() allows you to iterate the unpacking process of data. A buffer is required so the iteration can happen. It returns a formatted string type.
No, the data present in a numpy array is already packed in memory. Therefore using struct is pointless in this scenario.
Conclusion
We have looked at struct.pack() and multiple functions that work alongside. Struct module provides us the ability to work with C-type structures and manipulate struct values.