The essentials

Quick reference

One focused task per row. Jump to the related section for complete, working examples.

UseSyntaxExamples
Serialize to bytespayload = pickle.dumps(value, protocol=pickle.HIGHEST_PROTOCOL)View examples
Load trusted bytesvalue = pickle.loads(payload)View examples
Write a pickle filewith open(path, 'wb') as stream: pickle.dump(value, stream, protocol=5)View examples
Read the newest protocolprotocol = pickle.HIGHEST_PROTOCOLView examples
Target protocol 4payload = pickle.dumps(value, protocol=4)View examples
Read the default protocolprotocol = pickle.DEFAULT_PROTOCOLView examples
Customize serialized statedef __getstate__(self): return {'version': 1, 'value': self.value}View examples
Restore validated statedef __setstate__(self, state): self.value = validate(state)View examples
Define a reductiondef __reduce__(self): return (type(self), (self.value,))View examples
Register a type reducercopyreg.pickle(ValueType, reduce_value)View examples
Use a private reducer tablepickler.dispatch_table = {ValueType: reduce_value}View examples
Emit an external identifierdef persistent_id(self, obj): return ('Record', obj.key)View examples
Resolve an external identifierdef persistent_load(self, pid): return repository.fetch(pid)View examples
Open a shelfwith shelve.open(path, flag='c', writeback=False) as db: use(db)View examples
Persist a mutable updatevalue = db[key]; value.append(item); db[key] = valueView examples
Synchronize a shelfdb.sync()View examples
Disassemble without loadingpython -m pickletools payload.pickleView examples
Override global resolutiondef find_class(self, module, name): raise pickle.UnpicklingError('globals forbidden')View examples

pickle preserves Python object graphs, including shared references and custom class state; that power also lets malicious payloads invoke code during loading. It is therefore an internal trusted-data format, not a safe interchange format. shelve adds string-keyed persistence over pickle and a DBM backend, but does not add trust, concurrency, or cross-platform guarantees.

Step by step

Detailed examples

01

Round-trip trusted object graphs

dumps and dump serialize an object graph; loads and load reconstruct it by importing referenced definitions. Shared references and recursive structures are preserved within a pickle operation. The format is Python-specific and class code must remain importable, so schema-oriented JSON, CSV, or a database is usually better for long-lived cross-language data.

Preserve a shared reference
import pickle

shared = [1, 2]
value = {"left": shared, "right": shared}
restored = pickle.loads(pickle.dumps(value, protocol=4))
print(restored)
print(restored["left"] is restored["right"])
Output
{'left': [1, 2], 'right': [1, 2]}
True
Back to quick reference ↑
02

Choose protocols for the oldest reader

Higher protocols can be smaller or faster but require a sufficiently new Python. Protocol 5 supports out-of-band buffers and became the default protocol in Python 3.14; HIGHEST_PROTOCOL is appropriate only when every reader is controlled. Persist the producer version and schema separately, and test migrations before upgrading writers.

Inspect protocol constants without version assumptions
import pickle

print(pickle.HIGHEST_PROTOCOL >= pickle.DEFAULT_PROTOCOL)
payload = pickle.dumps({"ok": True}, protocol=4)
print(pickle.loads(payload))
Output
True
{'ok': True}
Back to quick reference ↑
03

Evolve class state explicitly

Implement __getstate__ to remove transient values and __setstate__ to validate or migrate restored state. Keep definitions at module scope with stable qualified names. Renaming modules or classes breaks ordinary loading unless compatibility shims or a custom Unpickler map old names; constructors are not necessarily called during unpickling, so validation belongs in restoration logic too.

Exclude a derived cache from state
import pickle

class Record:
    def __init__(self, value: int):
        self.value = value
        self.cache = value * 10
    def __getstate__(self):
        return {"value": self.value}
    def __setstate__(self, state):
        self.value = state["value"]
        self.cache = self.value * 10

record = pickle.loads(pickle.dumps(Record(7), protocol=4))
print(record.value, record.cache)
Output
7 70
Back to quick reference ↑
04

Register stable reductions for controlled types

A reduction specifies the callable and arguments used to rebuild an object. Prefer a simple importable reconstruction function and primitive state. copyreg registers reductions globally for a type, while a Pickler dispatch_table can isolate policy to one writer. Never accept a reducer supplied by untrusted data; loading chooses and invokes globals encoded in the pickle.

Restore through an explicit reduction
import pickle

class Point:
    def __init__(self, x: int, y: int):
        self.x, self.y = x, y
    def __reduce__(self):
        return (Point, (self.x, self.y))

point = pickle.loads(pickle.dumps(Point(3, 4), protocol=4))
print(point.x, point.y)
Output
3 4
Back to quick reference ↑
05

Keep external objects outside the pickle

Pickler.persistent_id can replace selected objects with application identifiers, and Unpickler.persistent_load resolves them from a trusted store. Include a type tag and validate every identifier to prevent confused-deputy lookups. This separates object-graph structure from large or shared records, but the pickle stream itself remains executable and trusted-only.

Model tagged persistent identifiers
def resolve(pid: tuple[str, int], records: dict[int, str]) -> str:
    kind, key = pid
    if kind != "Record":
        raise ValueError("unsupported persistent object")
    return records[key]

print(resolve(("Record", 7), {7: "saved"}))
Output
saved
Back to quick reference ↑
06

Treat shelve as a single-writer trusted store

Shelf keys are strings and values are pickled. The backing DBM implementation and files vary by platform, and concurrent read/write access is not supported unless the underlying implementation explicitly provides it. With writeback=False, mutate a value by assigning it back; writeback=True caches every accessed value and can consume memory or make close unexpectedly slow.

Persist and reopen a temporary shelf
import shelve
import tempfile

with tempfile.TemporaryDirectory() as directory:
    path = directory + "/state"
    with shelve.open(path) as db:
        db["items"] = [2, 3]
    with shelve.open(path, flag="r") as db:
        print(db["items"])
        print(sorted(db.keys()))
Output
[2, 3]
['items']
Back to quick reference ↑
07

Never load an untrusted pickle

Unpickling can execute arbitrary code before a returned value can be inspected. Authentication can detect tampering only when secret-key handling and verification occur before loading; it does not make an untrusted producer safe. pickletools can disassemble or optimize opcodes without executing them, but static review is not a complete sandbox. Run migrations from isolated backups with least privilege.

Inspect harmless pickle opcodes
import io
import pickle
import pickletools

payload = pickle.dumps([1, 2], protocol=0)
operations = [opcode.name for opcode, argument, position in pickletools.genops(payload)]
print(operations[0], operations[-1])
print("GLOBAL" in operations)
Output
MARK STOP
False
Back to quick reference ↑

Local code tester

Round-trip a trusted object graph

Serialize a small internal value with an explicit protocol and verify shared-reference preservation.

Runs in your browser
Output
Press Run to load Python locally.

Sources and further reading

References

Authoritative documentation used to verify and expand this cheat sheet.

  1. Python Software Foundationpickle — Python object serializationdocs.python.org
  2. Python Software Foundationshelve — Python object persistencedocs.python.org
  3. Python Software Foundationpickletools — Tools for pickle developersdocs.python.org
  4. Python Software Foundationcopyreg — Register pickle support functionsdocs.python.org
  5. Python Software FoundationPEP 574 — Pickle protocol 5 with out-of-band datapeps.python.org

Help us improve

Found a typo or missing example?

Tell us what would make this cheat sheet clearer, more complete, or more useful.

Share feedback