Skip to main content

Python Bytes and Bytearray

Data Types Satellite

Bytes & Bytearray

Python treats text (`str`) and binary (`bytes`) separately. Learn how to read/write binary files, encode/decode strings, and mutate buffers.

Bytes literals

A bytes object is an immutable sequence of integers in the range 0–255. Prefix a literal with b:

data = b"Python"        # each character is one byte
data[0] # 80 — indexing yields an int, not a byte
data[:3] # b'Pyt' — slicing yields bytes
b"\x00\xff" # arbitrary bytes via \x escapes
bytes([80, 121]) # b'Py' — from a list of ints

Only ASCII characters can appear directly in a bytes literal; anything else must be escaped or produced by encoding.

Encoding & decoding

Text and bytes are not interchangeable. Convert between them explicitly:

data = "café".encode("utf-8")   # b'caf\xc3\xa9' — str -> bytes
text = data.decode("utf-8") # 'café' — bytes -> str
  • Always name the encoding when talking to files, networks, or other systems; don't rely on the platform default.
  • Mismatched encodings raise UnicodeDecodeError. Handle unknown input with errors="replace" or errors="ignore".
data.decode("ascii", errors="replace")   # substitutes � for non-ASCII bytes

Default to UTF-8 unless a data source dictates otherwise.

bytes vs bytearray

TypeMutable?When to use
bytesNoImmutable binary data, network responses, file contents
bytearrayYesIn-place edits, building/streaming buffers
buffer = bytearray(b"abc")
buffer[0] = ord("A") # b'Abc' — edit in place
buffer.append(0x21) # b'Abc!'
bytes(buffer) # freeze into an immutable copy

Because bytes is immutable, repeatedly concatenating it in a loop is slow—collect chunks in a bytearray (or a list) and join once.

Common operations

from pathlib import Path

Path("image.png").read_bytes() # read a binary file
Path("copy.bin").write_bytes(data) # write bytes to disk

data.hex() # '636166c3a9' — bytes to hex string
bytes.fromhex("636166") # b'caf' — hex string back to bytes

Slicing, in, and len() all work on bytes just like strings, but every result stays bytes.

Next up in your learning path

Frequently Asked Questions

What is the difference between str and bytes in Python?

A str holds Unicode text; bytes holds raw binary data as integers 0–255. You cannot mix them—convert text to bytes with .encode("utf-8") and bytes back to text with .decode("utf-8"). Files and sockets operate on bytes.

text = "café"
data = text.encode("utf-8") # b'caf\xc3\xa9'
data.decode("utf-8") # 'café'

When should I use bytearray instead of bytes?

Use bytearray when you need to modify binary data in place—setting individual bytes, appending, or building a buffer incrementally. Use bytes for fixed, read-only data.

buf = bytearray(b"abc")
buf[0] = ord("A") # b'Abc'
buf.append(0x21) # b'Abc!'
bytes(buf) # freeze into immutable bytes

Why do I get UnicodeDecodeError?

It means you decoded bytes with the wrong encoding—for example reading UTF-8 data as ASCII. Decode with the correct encoding, or pass errors="replace" or errors="ignore" to tolerate malformed bytes.

data = "café".encode("utf-8")
data.decode("ascii") # UnicodeDecodeError
data.decode("ascii", errors="replace") # 'caf��'

Why does indexing bytes give me a number?

Indexing a bytes object returns the integer value of that byte (0–255), not a one-byte bytes object. To get a single byte back as bytes, slice instead.

data = b"Py"
data[0] # 80 — an int
data[0:1] # b'P' — a bytes object