How to Use __getstate__ and __setstate__ for Pickle in Python

Customize Python object serialization with the pickle __getstate__ and __setstate__ hooks to control exactly what data is stored and how it is restored.

Medium Python 3.9+ Aug 9, 2026 OOP & classes 13 views 0 copies

Python code

29 lines
Python 3.9+
import pickle

class Temperature:
    def __init__(self, celsius):
        self.celsius = celsius

    def __getstate__(self):
        """Customize what gets pickled."""
        state = self.__dict__.copy()
        # Convert to Fahrenheit for storage (simulate transformation)
        state['fahrenheit'] = (self.celsius * 9 / 5) + 32
        # Remove the original attribute to reduce payload
        del state['celsius']
        return state

    def __setstate__(self, state):
        """Customize how the object is restored."""
        # Reconstruct celsius from stored fahrenheit
        self.celsius = (state['fahrenheit'] - 32) * 5 / 9
        self.__dict__.update(state)

if __name__ == "__main__":
    original = Temperature(25)
    data = pickle.dumps(original)
    restored = pickle.loads(data)
    print(f"Original celsius: {original.celsius}")
    print(f"Pickled state: {data!r}")
    print(f"Restored celsius: {restored.celsius:.2f}")
    print(f"Restored has fahrenheit: {hasattr(restored, 'fahrenheit')}")

Output

stdout
Original celsius: 25
Pickled state: b'\x80\x04\x95,\x00\x00\x00\x00\x00\x00\x00}\x94\x8c\nfahrenheit\x94K\x8c\x96\x94s.'
Restored celsius: 25.00
Restored has fahrenheit: True

How it works

The __getstate__ method lets you define what pickle actually serializes, returning a custom state dictionary instead of the default self.__dict__. Here, we compute a Fahrenheit value and drop the original celsius key to shrink the payload. On unpickling, __setstate__ receives that stored state and rebuilds the celsius attribute while keeping the fahrenheit value, so the restored object carries both. This pattern gives you full control over the pickle format, which is useful for versioning or storing derived data.

Common mistakes

  • Forgetting to delete keys in __getstate__, leaving duplicate data in the pickle payload.
  • Assuming __setstate__ receives the original __dict__; it receives whatever __getstate__ returned.
  • Mutating self.__dict__ directly in __setstate__ without updating it properly can lose attributes.

Variations

  1. Use __reduce__ and __reduce_ex__ for even more control over pickling, including custom constructors.
  2. Return a tuple (state, slots) from __getstate__ when working with classes using __slots__.

Real-world use cases

  • Saving ML model snapshots where only essential features are serialized to keep file size small.
  • Storing intermediate data in a distributed cache without persisting transient computed attributes.
  • Maintaining backwards compatibility when the class schema changes between releases.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from OOP & classes

Related tutorials and quizzes for this topic.