Python

How Python Handles Binary Data

Explore Python's built-in tools for working with raw bytes, from files and structs to memory views and arrays. Learn how to read, write, and interpret binary data without dropping down to C.

July 2026 6 min read 11 views 0 hearts

How Python Handles Binary Data (And Why You Should Care)

You might think binary data is something only low-level programmers deal with--the kind of folks who write device drivers or network protocols in C. But Python actually makes working with raw bytes surprisingly intuitive, and once you understand how it works, you'll start seeing opportunities to use it everywhere.

Let me show you what I mean.

The Big Difference Between Text and Binary

Here's something that trips up a lot of Python developers: when you open a file with open("data.txt"), Python treats it as text. It assumes you're dealing with characters, so it tries to decode the bytes into strings.

But what if you're reading an image, a zip file, or a custom binary format? That's when you need to tell Python "no, give me the raw bytes."

# This gives you a string
with open("photo.jpg") as f:
    data = f.read()  # Python tries to decode this as text

# This gives you bytes
with open("photo.jpg", "rb") as f:
    data = f.read()  # Python gives you the raw bytes

The "rb" mode is the key difference. The "b" stands for binary, and it changes everything.

Working with Raw Bytes

When you read a file in binary mode, Python doesn't give you a string. It gives you a bytes object. A bytes object looks similar to a string but has some important differences:

data = b"Hello"  # This is bytes, not a string
print(data[0])   # Output: 72 (the ASCII value of 'H')

Notice that indexing into bytes gives you an integer, not a character. This makes sense when you think about it: bytes are numbers between 0 and 255, and Python treats them as such.

The Bytes vs Bytearray Distinction

Python actually has two main types for handling binary data: bytes and bytearray. The difference is mutability.

# bytes is immutable
data = b"hello"
# data[0] = 72  # This would raise an error

# bytearray is mutable
data2 = bytearray(b"hello")
data2[0] = 72  # This works fine

If you're manipulating binary data on the fly, bytearray is usually more practical. If you're just reading something read-only, bytes is fine.

The struct Module: Your Binary Swiss Army Knife

Here's where things get really interesting. When you're dealing with binary file formats or network protocols, raw bytes aren't enough--you need to interpret them as meaningful data types like integers, floats, and strings.

Python's struct module shines here. It lets you pack and unpack binary data using format strings that describe exactly how the bytes should be interpreted.

import struct

# Pack data into bytes
packed = struct.pack('>i4s', 42, b'Test')
# '>' means big-endian, 'i' means integer, '4s' means 4-byte string

# Unpack bytes into data
number, text = struct.unpack('>i4s', packed)
print(number)  # 42
print(text)    # b'Test'

The format specifiers might look cryptic at first, but they're incredibly powerful. Need to parse a 32-bit floating point number from a binary file? 'f' handles that. Working with network protocols that use network byte order? '!' (which is shorthand for big-endian network order) has you covered.

Real-World Example: Reading a PNG File Header

Let me show you something practical. PNG images have a specific binary header structure. With Python, you can actually parse this without any image library:

import struct

with open("image.png", "rb") as f:
    # Read the first 8 bytes (PNG signature)
    signature = f.read(8)

    # Read the IHDR chunk header
    chunk_length = struct.unpack('>I', f.read(4))[0]
    chunk_type = f.read(4)

    if chunk_type == b'IHDR':
        # Read width, height, bit depth, color type, etc.
        width, height = struct.unpack('>II', f.read(8))
        print(f"Image dimensions: {width}x{height}")

Now you're reading binary data like a pro. You don't need to use PIL or OpenCV just to get basic information from an image.

Memory Views and the array Module

When you're dealing with large amounts of binary data, performance matters. Python provides the memoryview object to work with slices of binary data without copying:

data = bytearray(b"Hello World")
view = memoryview(data)
slice = view[0:5]
# slice is a memoryview, not a copy of the data
# Modifying slice also modifies data

For working with homogeneous binary arrays (all the same data type), Python's array module is more memory efficient than lists:

from array import array

# Create an array of unsigned integers
data = array('I', [1, 2, 3, 4, 5])

# Write to a file
with open("numbers.bin", "wb") as f:
    data.tofile(f)

# Read it back
recovered = array('I')
with open("numbers.bin", "rb") as f:
    recovered.fromfile(f, 5)

When Binary Data Makes Sense

Not everything needs to be binary. Here are the scenarios where I reach for Python's binary tools:

  1. Reading or writing file formats (images, audio, archives)
  2. Network programming (protocol buffers, custom protocols)
  3. Interfacing with hardware (serial ports, device drivers)
  4. Working with legacy data (old database files, proprietary formats)
  5. Performance-critical sections (binary operations are faster than text parsing)

The Bottom Line

Python's binary data handling is one of those features that quietly power a lot of real-world applications. The bytes and bytearray types give you the raw building blocks, while struct lets you interpret that data as meaningful values. And tools like memoryview and the array module ensure you can do it efficiently.

The next time you're debugging a network protocol or trying to read a custom binary file format, remember: Python has your back. You don't need to drop down to C or shell out to external tools. The power is already there, waiting in the standard library.

Comments

Questions, corrections, and tips stay visible for everyone reading this page.

0 in thread

Join the discussion

Shown next to your comment.

Up to 4,000 characters

No comments yet

Be the first to leave a note — it helps the next reader.