Skip to content

Python pickle — Object Serialization

pickle converts almost any Python object into a byte stream (serializing / “pickling”) and back again (deserializing / “unpickling”). Use it to save program state, cache results, or pass objects between Python processes.

quickstart.py
import pickle
 
data = {"name": "Ada", "scores": [88, 92], "active": True}
 
blob = pickle.dumps(data)        # object -> bytes
restored = pickle.loads(blob)    # bytes -> object
print(restored)                  # {'name': 'Ada', 'scores': [88, 92], 'active': True}
print(restored == data)          # True

Never unpickle data you do not trust. Unpickling can execute arbitrary code, so a malicious pickle file can take over your program. Only load pickles you created yourself or received from a trusted source. For untrusted or cross-language data, use JSON instead.

Like json, pickle has a string/bytes pair and a file pair.

FunctionDirectionWorks with
pickle.dumps(obj)Object → bytesA bytes object.
pickle.loads(bytes)bytes → ObjectA bytes object.
pickle.dump(obj, file)Object → bytesA binary file.
pickle.load(file)bytes → ObjectA binary file.

Pickle writes binary, so open files in binary mode ("wb" / "rb").

files.py
import pickle
 
model = {"weights": [0.1, 0.2, 0.3], "bias": 0.5}
 
# Save
with open("model.pkl", "wb") as f:
    pickle.dump(model, f)
 
# Load
with open("model.pkl", "rb") as f:
    loaded = pickle.load(f)
 
print(loaded["bias"])   # 0.5

Pickle handles far more than JSON: nearly all built-in types, plus custom class instances.

PicklableNot picklable
int, float, str, bool, NoneOpen file handles
list, tuple, dict, setNetwork sockets, DB connections
Nested combinations of the aboveLambdas (use a named function)
Instances of your own classesGenerators / running threads
custom_objects.py
import pickle
 
class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __repr__(self):
        return f"Point({self.x}, {self.y})"
 
p = Point(3, 4)
blob = pickle.dumps(p)
p2 = pickle.loads(blob)
print(p2)          # Point(3, 4)
print(p2 is p)     # False -> a brand-new, equal object

To unpickle a custom class, its class definition must be importable in the program doing the loading.

Pickle has several binary protocol versions; higher numbers are more efficient. Use pickle.HIGHEST_PROTOCOL for the best, or pickle.DEFAULT_PROTOCOL for broad compatibility.

protocols.py
import pickle
 
data = list(range(1000))
blob = pickle.dumps(data, protocol=pickle.HIGHEST_PROTOCOL)
print(len(blob), "bytes")
print(pickle.loads(blob)[:3])   # [0, 1, 2]
sketch pickle against JSON on the same data p5.js
A thousand small records, dumped and loaded both ways. pickle is smaller and faster on every measure because it writes a binary format aimed at one language, while JSON writes text that anything can read. That is the whole trade: pickle wins on numbers and loses on everything else -- it is Python-only, version-sensitive, unreadable by a human, and unpickling untrusted data can execute arbitrary code.
pickleJSON
OutputBinary, Python-onlyText, language-neutral
TypesAlmost any Python objectBasic types only
Human-readableNoYes
Safe with untrusted dataNoYes
Best forCaching/state between Python programsAPIs, configs, data exchange

Choose JSON for data shared with other systems or users; choose pickle only for trusted, Python-to-Python data that JSON can’t represent.

  • Binary mode required — open files with "wb"/"rb", not "w"/"r".
  • Cross-version risk — a pickle made in one Python version may not load in another.
  • Lambdas don’t pickle — use a module-level def function instead.
  • Security — never loads/load data from an untrusted source.

Exercise 2 – Confirm equality after a round-trip

Section titled “Exercise 2 – Confirm equality after a round-trip”
  • pickle serializes almost any Python object to bytes and back.
  • Use dumps/loads for bytes, dump/load for binary files.
  • It handles custom classes (the class must be importable to unpickle).
  • Never unpickle untrusted data — it can run arbitrary code; prefer JSON for shared data.
  • Pick pickle for trusted Python-to-Python state; pick JSON for interoperability.

pch.coffeeTagline

pch.coffeeCta

pch.feedbackHeading

pch.feedbackSubheading