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.