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.
Python code
29 linesimport 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
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
- Use __reduce__ and __reduce_ex__ for even more control over pickling, including custom constructors.
- 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
More from OOP & classes
- Add property getter setter validation in Python easy
- Binary Tree Inorder Traversal in Python easy
- Borg pattern shared state in Python medium
- Bridge Pattern in Python: Separate Abstraction from Implementation medium
- Composable Predicates with the &, |, ~ Operators in Python medium
- Composition over Inheritance: How to Build a Wallet Account in Python easy
Keep learning
Related tutorials and quizzes for this topic.