Python Struct Tutorial – Complete Guide

If you’re interested in games or code handling binary data, then Python’s struct module will undoubtedly spark your interest. In this tutorial, we’ll unlock the puzzling but powerful piece of Python mastery, known as the struct module. By the end of this, you’ll have a solid foundation to dive deeper and create your own Python projects using the struct module.

Understanding Python struct

Python’s struct module offers a way to handle binary data (non-text data). It provides pack() and unpack() functions for working with variable-length binary record formats.

Here’s the catch – Why should you learn about Python’s struct module? As coding enthusiasts or game developers, there will be times when you need to handle binary data or records. That’s where Python struct comes into play. Its ability to convert between Python values and C structs represented as Python bytes objects, allows for efficient manipulation of binary data.

Now that we’ve grasped what Python struct is and why it’s crucial for us to learn it, let’s dive into some coding!

CTA Small Image
FREE COURSES AT ZENVA
LEARN GAME DEVELOPMENT, PYTHON AND MORE
ACCESS FOR FREE
AVAILABLE FOR A LIMITED TIME ONLY

The Basics of Python struct

Python struct deals with bytes, so let’s start by understanding the ‘format’ argument which is a string that contains one or more characters. This defines the structure of our binary data. Each character represents a specific type of data, and there can be optional prefixes.

# importing struct module
import struct

# use 'b' format to tell we are using bytes
print(struct.pack('b', 15))

In the above code snippet, we start by importing the struct module. The pack() function uses the string ‘b’, which tells it to treat the number 15 as bytes.

The output looks something like this:

b'\x0f'

This is a bytes object representing the number 15. This simple bytes-packing can serve as a building block for managing more complex binary data, such as in your next game project!

Taking It Further With Python struct

Now that we understand the basics, let’s consider a more elaborate example:

# Simple game score record
username = 'Zenva'
level = 5
score = 20000

# Packing the data
binary_data = struct.pack('5sii', username.encode('utf-8'), level, score)
print(binary_data)

Here, we are packing a string and two integers into a binary format. We use the ‘5sii’ format i.e., a 5-character string (‘5s’) and two integers (‘ii’). We also encode the username string to convert it into bytes before packing.

The output will be a sequence of bytes that can be written to a file, sent over a network, or used anywhere that binary data is needed.

Unpacking Binary Data

After packing data into binary format with the struct module, we’ll often need to unpack it back into Python values. Let’s see how to do that:

binary_data = b'\x00\x04\x00\x00\x00\x20\x00\x00'
unpacked_data = struct.unpack('i2i', binary_data)

# Output
print(unpacked_data)

The ‘i2i’ argument tells the unpack() function that the data consists of three integers. The output will be a tuple with these three integers.

Alignment and Byte Order

When working with the struct module, understanding alignment and byte order is important. Alignment refers to positioning of data in bytes. By default, native byte order, size, and alignment are determined according to your platform.

format = "=i2i"
native_format = "i2i"

print(f'Native format: {struct.calcsize(native_format)} bytes')
print(f'Standard format: {struct.calcsize(format)} bytes')

The “=” character in the format string specifies standard, rather than native, size and alignment.

Automatic Padding

Sometimes, we need padding in our binary data. This can be automatic padding provided by Python struct or manual padding.

# Padding with zeroes
padded_data = struct.pack('i3xi', 3, 7)

print(padded_data)

The ‘x’ character in the format string is for padding. It means “pad byte”. No value is needed to pack it.

Working with Files

Struct module really comes handy when you are working with binary files. Let’s delve into reading and writing to files using Struct module

# Write binary data to a file
with open('data.bin', 'wb') as f:
    f.write(binary_data)

# Read the data back from the file
with open('data.bin', 'rb') as f:
    read_data = f.read()

# Unpack and print the data
unpacked_data = struct.unpack('i2i', read_data)
print(unpacked_data)

By using ‘wb’ and ‘rb’ modes for writing and reading files, we treat the data as binary, which aligns with the purpose of the struct module.

Stay tuned for the final part of this tutorial, where we dive deeper into the struct module, including some of its more advanced functionalities!

Handling Nested Structures

Python’s struct module also allows you to manage nested binary data structures. Let’s look at an example of how to handle nested structures with the struct module.

# Here's the nested binary data structure
data = [('Zenva', 5, 20000), ('Coder', 7, 40000), ('DevGuru', 10, 60000)]

# Packing the nested data
binary_data = struct.pack('3sii'*len(data), *(s.encode('utf-8'), l, sc for s, l, sc in data))

print(binary_data)

In this example, we’re packing a list of tuples, each containing a string and two integers. The format string ‘3sii’ is repeated for each tuple in the list.

Using Metacharacters and Compound Format Strings

The struct format string can contain metacharacters, which are like modifiers. Here’s an example using the repetition count metacharacter:

struct.pack('3s10x6s', b'ZEN', b'40000')

In the format string ‘3s10x6s’, ‘3s’ means a three-byte string, ’10x’ means 10 padding bytes, and ‘6s’ means a six-byte string.

You can also combine multiple format strings into one to handle more complex data structures.

# Combined format strings
format = struct.Struct('3s 2i')
data = format.pack(b'ZEN', 5, 40000)

print(data)

Dealing with Bits

Sometimes, you may need to operate at the level of individual bits. That’s when the bitwise operators come into play. Here’s an example:

# Set a bit
flags = 0
flags |= 1 << 5

# Clear a bit
flags &= ~(1 << 5)

# Flip a bit
flags ^= 1 << 5

# Test a bit
if flags & (1 << 5):
    print('The bit is set')
else:
    print('The bit is not set')

These operations make it easy to work with individual bits in your binary data.

Working with Floats and Doubles

The struct module can also handle floating point numbers and doubles. The format characters for these are ‘f’ and ‘d’, respectively.

# Float and double
f = 12.34
d = 56.78

# Packing and unpacking
packed_data = struct.pack('fd', f, d)
unpacked_data = struct.unpack('fd', packed_data)

print(unpacked_data)

In this example, a float and a double are packed into bytes and then unpacked back into Python values.

There you have it, that was a deep dive into Python’s struct module. This module is an excellent tool in your Python arsenal, especially if you plan to work with binary data in fields such as game development or data analysis. Keep honing your skills and happy coding!

Where To Go Next

Having acquired valuable insights into Python’s struct module, you might be wondering – what’s next in your Python journey? Continuing to learn and expand your skill-set is the key to unlocking higher potential in your coding career.

Beyond individual courses, we at Zenva are proud to offer our Python Mini-Degree. This comprehensive collection of courses on Python programming includes everything from coding basics and algorithms to complex game and app development. This extensive program is designed to assist both newcomers to coding and seasoned programmers. The Mini-Degree covers:

  • Python Coding Basics
  • Algorithms
  • Object-Oriented Programming
  • Game Development
  • App Development using popular Python libraries and frameworks such as Pygame, Tkinter, and Kivy

Our Python Mini-Degree allows you to learn at your own pace, offering 24/7 access to all courses. Interwoven in the courses are challenges and quizzes to reinforce what you learn and strengthen your coding muscles. Moreover, you’ll get hands-on experience by working on step-by-step projects that let you apply coding knowledge to create games, apps, and real-world projects.

Conclusion

Delving into Python’s struct module has opened up the world of handling binary data with ease and precision. From game development to analyzing binary files, the applications of this module are as diverse as they are interesting. We hope that these insights into Python’s struct module have not only enriched your knowledge but have also ignited a curiosity to learn more.

As we wrap up this deep dive into Python binary data handling, remember that every line of code you write elevates your Python skills. Don’t let this be the end of your learning journey with us. At Zenva, we strive to be a part of your path to coding mastery. Whether it’s our extensive Python Mini-Degree or any other specialized course, each step you take with us edges you closer to becoming a seasoned coder. Let’s continue to unlock the world of Python together. Happy Coding!

Did you come across any errors in this tutorial? Please let us know by completing this form and we’ll look into it!

FREE COURSES
Python Blog Image

FINAL DAYS: Unlock coding courses in Unity, Godot, Unreal, Python and more.