![]()
In Python, every object has a dynamic dictionary (__dict__) that stores its attributes. While flexible, this can consume more memory and slow down attribute access.
__slots__ helps reduce memory usage by preventing the creation of __dict__ and restricting attributes to a fixed set.
Improves attribute lookup speed by avoiding dictionary overhead.
Useful for performance optimization in applications with many instances.
1. Understanding __slots__
By default, Python classes use a dictionary (__dict__) to store attributes dynamically.
Example: Regular Class with __dict__
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
p = Person("Alice", 30)
print(p.__dict__)
# Output: {'name': 'Alice', 'age': 30}
Problem:
- Each instance has a
__dict__, consuming extra memory. - Attribute lookup is slower due to dictionary overhead.
2. Using __slots__ to Optimize Memory Usage
The __slots__ attribute restricts instances to a fixed set of attributes and removes the __dict__.
Example: Defining __slots__
class Person:
__slots__ = ('name', 'age') # Restrict attributes
def __init__(self, name, age):
self.name = name
self.age = age
p = Person("Alice", 30)
print(p.name) # Output: Alice
# p.address = "NYC" # AttributeError: 'Person' object has no attribute 'address'
What happens here?
- No
__dict__→ Memory-efficient storage. - Restricted attributes → Only
nameandageare allowed. - Faster attribute access → Directly stored in a lightweight structure.
3. Comparing Memory Usage (__dict__ vs __slots__)
Using sys.getsizeof() to measure memory usage.
Example: Memory Comparison
import sys
class Regular:
def __init__(self, x):
self.x = x
class Slotted:
__slots__ = ('x')
def __init__(self, x):
self.x = x
r = Regular(10)
s = Slotted(10)
print(sys.getsizeof(r.__dict__)) # Output: 112 (dict overhead)
# print(s.__dict__) # AttributeError: No __dict__ (saves memory)
Why does __slots__ save memory?
- Regular class: Stores attributes in a dictionary (
__dict__), which has overhead. - Slotted class: Uses a tuple-like structure (lower memory footprint).
4. When to Use __slots__
Use __slots__ when:
- You need thousands/millions of objects (e.g., data-heavy applications).
- Memory optimization is a priority.
- Your class has fixed attributes (no dynamic attributes needed).
Avoid __slots__ when:
- You require dynamic attributes (e.g., adding attributes at runtime).
- You need multiple inheritance (not well-supported with
__slots__). - You frequently use
dir(),vars(), or other reflection methods (which rely on__dict__).
5. Inheritance and __slots__
5.1 Single Inheritance with __slots__
When a subclass inherits a slotted class, it can define new slots.
class Parent:
__slots__ = ('a',)
class Child(Parent):
__slots__ = ('b',)
obj = Child()
obj.a = 10
obj.b = 20
# obj.c = 30 # AttributeError: 'Child' object has no attribute 'c'
Each class must define its own __slots__ for new attributes.
5.2 __slots__ with Multiple Inheritance (Limitations)
Python does not allow multiple slotted parent classes without a fallback __dict__.
class A:
__slots__ = ('x',)
class B:
__slots__ = ('y',)
class C(A, B): # Error: Multiple inheritance with slots
pass
Solution: Use __slots__ = ('x', 'y') in C OR avoid __slots__ in multiple-inheritance scenarios.
6. Allowing __dict__ with __slots__
If needed, you can explicitly allow dynamic attributes while keeping __slots__ benefits.
class Config:
__slots__ = ('setting1', 'setting2', '__dict__')
cfg = Config()
cfg.setting1 = "ON"
cfg.new_attr = "Allowed" # Now works, because __dict__ is present
Why?
__dict__is re-enabled, allowing dynamic attributes.__slots__still optimizes existing attributes.
7. Summary Table
| Feature | Without __slots__ | With __slots__ |
|---|---|---|
| Memory Usage | Higher (uses __dict__) | Lower (no __dict__) |
| Attribute Access | Slower (dictionary lookup) | Faster (direct access) |
| Dynamic Attributes | Allowed | Not allowed (unless __dict__ is explicitly added) |
| Multiple Inheritance | Works normally | Limited support |
Reflection (dir(), vars()) | Works as expected | May not work correctly |
