__slots__ declares a fixed set of attribute names for instances. CPython then stores those attributes in a compact structure instead of a per-instance __dict__ (by default), which can save memory when you create many instances.
Effects:
- Faster attribute access and lower memory for large populations of objects.
- You cannot assign arbitrary new attributes unless you also include
__dict__in slots. - Inheritance needs care: subclasses may need their own
__slots__. - Some features (weakrefs) need explicit
__weakref__in slots.
class PointDict:
def __init__(self, x, y):
self.x = x
self.y = y
class PointSlots:
__slots__ = ("x", "y")
def __init__(self, x, y):
self.x = x
self.y = y
p = PointSlots(1, 2)
print(p.x, p.y)
# p.z = 3 # AttributeError: 'PointSlots' object has no attribute 'z'
# print(p.__dict__) # AttributeError (no instance dict)When to use: Millions of simple objects (graph nodes, particles, rows). Skip for most app code; clarity beats micro-optimization until profiling says otherwise.