Skip to content
Home Python Python __slots__ — What They Are and When to Use Them

Python __slots__ — What They Are and When to Use Them

Where developers are forged. · Structured learning · Free forever.
📍 Part of: Advanced Python → Topic 11 of 17
Python __slots__ explained — how they reduce memory usage, speed up attribute access, prevent dynamic attribute addition, and when the trade-offs are worth it.
🔥 Advanced — solid Python foundation required
In this tutorial, you'll learn
Python __slots__ explained — how they reduce memory usage, speed up attribute access, prevent dynamic attribute addition, and when the trade-offs are worth it.
  • __slots__ replaces the per-instance __dict__ with fixed C-level descriptors — significant memory savings for many small objects.
  • With __slots__, you cannot add new attributes not declared in __slots__ at runtime.
  • Subclasses do not inherit __slots__ restrictions unless they also define __slots__.
✦ Plain-English analogy ✦ Real code with output ✦ Interview questions
Quick Answer

__slots__ replaces the instance __dict__ with a fixed set of slot descriptors. This reduces memory per instance (no dict overhead), slightly speeds up attribute access (direct offset vs hash lookup), and prevents adding new attributes at runtime. The trade-off: you lose dynamic attribute assignment and __dict__-based introspection.

Basic __slots__ Usage

Example · PYTHON
12345678910111213141516171819202122232425262728293031
import sys

# Without __slots__ — each instance has a __dict__
class PointDict:
    def __init__(self, x, y):
        self.x = x
        self.y = y

# With __slots__ — no __dict__, fixed attributes only
class PointSlots:
    __slots__ = ('x', 'y')

    def __init__(self, x, y):
        self.x = x
        self.y = y

p_dict  = PointDict(1.0, 2.0)
p_slots = PointSlots(1.0, 2.0)

print(sys.getsizeof(p_dict))   # ~48 bytes (object) + ~232 bytes (dict) = ~280
print(sys.getsizeof(p_slots))  # ~56 bytes — no dict

# __dict__ exists on PointDict but not PointSlots
print(hasattr(p_dict,  '__dict__'))  # True
print(hasattr(p_slots, '__dict__'))  # False

# Dynamic attribute assignment blocked
try:
    p_slots.z = 3.0  # AttributeError
except AttributeError as e:
    print(e)  # 'PointSlots' object has no attribute 'z'
▶ Output
280
56
True
False
'PointSlots' object has no attribute 'z'

Memory Savings at Scale

Example · PYTHON
1234567891011121314151617181920212223242526
import tracemalloc

class EventDict:
    def __init__(self, ts, kind, value):
        self.ts = ts; self.kind = kind; self.value = value

class EventSlots:
    __slots__ = ('ts', 'kind', 'value')
    def __init__(self, ts, kind, value):
        self.ts = ts; self.kind = kind; self.value = value

N = 100_000

tracemalloc.start()
events_dict = [EventDict(i, 'click', i * 1.5) for i in range(N)]
_, peak_dict = tracemalloc.get_traced_memory()
tracemalloc.stop()

tracemalloc.start()
events_slots = [EventSlots(i, 'click', i * 1.5) for i in range(N)]
_, peak_slots = tracemalloc.get_traced_memory()
tracemalloc.stop()

print(f"Dict:  {peak_dict / 1024 / 1024:.1f} MB")
print(f"Slots: {peak_slots / 1024 / 1024:.1f} MB")
print(f"Saving: {(1 - peak_slots/peak_dict)*100:.0f}%")
▶ Output
Dict: 56.2 MB
Slots: 18.4 MB
Saving: 67%

🎯 Key Takeaways

  • __slots__ replaces the per-instance __dict__ with fixed C-level descriptors — significant memory savings for many small objects.
  • With __slots__, you cannot add new attributes not declared in __slots__ at runtime.
  • Subclasses do not inherit __slots__ restrictions unless they also define __slots__.
  • If a class with __slots__ inherits from a class without __slots__, the __dict__ is still present.
  • Do not use __slots__ prematurely — only apply it when you have profiled memory usage and confirmed a problem.

Interview Questions on This Topic

  • QWhat is the purpose of __slots__ in Python and when would you use it?
  • QWhat happens if you try to add a new attribute to an object whose class uses __slots__?
  • QHow does __slots__ affect memory usage in Python?

Frequently Asked Questions

Does __slots__ work with inheritance?

Only if all classes in the hierarchy define __slots__. If the parent class does not define __slots__ (or defines it without including __dict__), instances will still have a __dict__. Each class in the hierarchy should define only the new slots it introduces, not repeat the parent's slots.

Can I use __slots__ with dataclasses?

Yes. Python 3.10+ added slots=True to @dataclass: @dataclass(slots=True). This automatically generates __slots__ from the field definitions, giving you the memory benefits without manually writing __slots__.

🔥
Naren Founder & Author

Developer and founder of TheCodeForge. I built this site because I was tired of tutorials that explain what to type without explaining why it works. Every article here is written to make concepts actually click.

← PreviousGIL — Global Interpreter LockNext →Abstract Base Classes in Python
Forged with 🔥 at TheCodeForge.io — Where Developers Are Forged