Serialization with pickle
pickle is Python's built-in serializer: it converts almost any Python object into a stream of bytes you can save or send, and reconstructs the exact object — types and all — when you read those bytes back.
Learn Serialization with pickle in our free Python course — an interactive lesson with runnable examples, a practice exercise and a quick reference.
Part of the free Python course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
Pickle is wonderfully convenient for saving program state and caching results between runs — but it comes with one serious safety rule that you must never forget. We'll cover the power and the danger together.
pickle.dumps(obj) turns an object into a bytes blob; pickle.loads(blob) turns it back. The reconstructed object is a full, independent copy with the original types intact:
Remember: the "s" in dumps / loads means "string of bytes" — these stay in memory. The file versions drop the "s".
pickle.dump(obj, file) writes the bytes straight to a binary file; pickle.load(file) reads them back. In a real program the file is opened with open("data.pkl", "wb") ; here we use an in-memory BytesIO buffer so it runs anywhere:
On disk you'd write with open("point.pkl", "wb") as f: pickle.dump(obj, f) and read with "rb" . The mode must be binary ( "wb" / "rb" ) because pickle produces bytes, not text.
Most built-in and custom objects pickle cleanly — including instances of your own classes. But a few things cannot be pickled: lambdas, open file handles, sockets, and (by default) locally-defined functions:
Pickle has several binary protocols , numbered 0 through 5. Higher protocols are more efficient and support more types, but older Python versions can't read them. You can pick one explicitly:
JSON and pickle solve overlapping problems with very different trade-offs. Pickle preserves exact Python types but is unsafe and Python-only; JSON is text, language-neutral, and safe — but loses some types:
Complete the round trip through an in-memory buffer. Replace each ___ , then run it.
✅ Pickle is binary — use "wb" to write and "rb" to read:
✅ Rewind the buffer first with buf.seek(0) (real files you reopen in "rb" ).
✅ Never unpickle untrusted bytes. Use JSON for external data, and reserve pickle for your own trusted state.
Build a GameState , pickle it into a buffer, then load it back and confirm the level, inventory, and a custom method all survived the round trip.
Lesson complete — you can persist Python objects safely!
You can serialize with dumps / loads , save to files with dump / load , pickle custom objects, know what can't be pickled, pick a protocol, and — most importantly — you'll never unpickle untrusted data. You also know exactly when JSON is the safer choice.
🚀 Up next: Config Files with configparser — read and write INI configuration.
Practice quiz
What type does pickle.dumps(obj) return?
- str
- dict
- bytes
- file
Answer: bytes. dumps serializes an object to a bytes blob; loads turns those bytes back into an object.
For a dict d, what is (pickle.loads(pickle.dumps(d)) is d)?
- False
- True
- None
- It raises an error
Answer: False. Unpickling builds a fresh, independent copy — it is equal (==) to the original but not the same object (is).
What is the difference between dumps/loads and dump/load?
- dump/load are faster versions of dumps/loads
- dumps/loads are only for dicts
- There is no difference
- dumps/loads work with bytes in memory; dump/load work with file objects
Answer: dumps/loads work with bytes in memory; dump/load work with file objects. The 's' versions return/accept a bytes string; the plain versions write to / read from a file-like object.
Which of these CANNOT be pickled?
- A dict of ints
- A lambda function
- A custom class instance
- A tuple of strings
Answer: A lambda function. Lambdas (and open files, sockets, generators) can't be pickled and raise PicklingError.
Why must you never pickle.loads data from an untrusted source?
- Unpickling can execute arbitrary code
- It is too slow
- It corrupts the data
- It only works on Windows
Answer: Unpickling can execute arbitrary code. A malicious pickle can run any code on your machine the moment you load it. Use JSON across trust boundaries.
What file mode must you use to write a pickle to disk?
- "w" (text)
- "a" (append)
- "wb" (binary)
- "r" (read)
Answer: "wb" (binary). Pickle produces bytes, so the file must be opened in binary mode — 'wb' to write, 'rb' to read.
After pickle.dump(obj, buf) on a BytesIO, what must you do before pickle.load(buf)?
- Nothing — load works immediately
- Call buf.seek(0) to rewind
- Call buf.flush()
- Re-create the buffer
Answer: Call buf.seek(0) to rewind. The cursor sits at the END after writing; seek(0) rewinds so load can read from the start (else EOFError).
What is pickle.HIGHEST_PROTOCOL in modern Python?
- 0
- 2
- 10
- 5
Answer: 5. Protocols are numbered 0 through 5; HIGHEST_PROTOCOL is 5, the newest and most efficient.
Which format preserves a Python tuple and set exactly through a round trip?
- JSON
- pickle
- CSV
- Both equally
Answer: pickle. pickle keeps exact Python types (tuples, sets, custom classes). JSON turns tuples into lists and rejects sets.
When is JSON the safer choice over pickle?
- When caching your own program's state
- When you need maximum speed
- When data is shared, stored long-term, or comes from outside
- When pickling custom classes
Answer: When data is shared, stored long-term, or comes from outside. JSON is text, language-neutral, and safe to parse — ideal for any data crossing a trust boundary.