Python struct — Core Concepts

What struct actually does

The struct module converts between Python values (integers, floats, strings) and C-style binary representations stored as Python bytes objects. It’s part of the standard library and requires no installation.

Two core operations drive everything:

  • struct.pack(format, v1, v2, ...) — takes Python values and produces a bytes object
  • struct.unpack(format, buffer) — takes a bytes object and produces a tuple of Python values

Format strings

A format string is a compact recipe describing the binary layout. Each character represents a data type:

CharacterC typePython typeSize (bytes)
bsigned charint1
Bunsigned charint1
hshortint2
Hunsigned shortint2
iintint4
Iunsigned intint4
ffloatfloat4
ddoublefloat8
schar[]bytesvariable

A count prefix like 4s means “4-byte string.” A prefix like 3i means “three integers.”

Byte order matters

The first character in a format string can specify byte order:

  • < — little-endian (Intel, most PCs)
  • > — big-endian (network byte order)
  • ! — network order (alias for big-endian)
  • = — native order
  • @ — native order with native alignment (default)

Getting byte order wrong is the most common struct bug. If you read a big-endian file with little-endian format, every multi-byte value will be scrambled.

How it works in practice

Suppose a binary file header contains a 4-byte magic number, a 2-byte version, and an 8-byte timestamp. You’d read it like this:

import struct

with open("data.bin", "rb") as f:
    header = f.read(14)

magic, version, timestamp = struct.unpack(">IHd", header)

The format >IHd says: big-endian, unsigned int (4 bytes), unsigned short (2 bytes), double (8 bytes) — 14 bytes total.

struct.Struct for repeated use

If you pack or unpack the same format many times, create a struct.Struct object. It pre-compiles the format string for speed:

header_fmt = struct.Struct(">IHd")
header_fmt.size   # 14
header_fmt.unpack(data)

Common misconception

People sometimes reach for struct to serialize general Python objects. That’s not its job. struct handles fixed-layout binary data — it has no concept of variable-length lists, nested objects, or optional fields. For general serialization, look at pickle, json, or msgpack.

One thing to remember

struct is a precision tool for fixed binary layouts. Know your format string, get the byte order right, and it will reliably bridge the gap between Python and any binary protocol or file format.

pythonstandard-librarybinary-data

See Also

  • Python Atexit How Python's atexit module lets your program clean up after itself right before it shuts down.
  • Python Bisect Sorted Lists How Python's bisect module finds things in sorted lists the way you'd find a word in a dictionary — by jumping to the middle.
  • Python Contextlib How Python's contextlib module makes the 'with' statement work for anything, not just files.
  • Python Copy Module Why copying data in Python isn't as simple as it sounds, and how the copy module prevents sneaky bugs.
  • Python Dataclass Field Metadata How Python dataclass fields can carry hidden notes — like sticky notes on a filing cabinet that tools read automatically.