Unlock Massive Memory Savings in Python with __slots__: A Deep Dive
This article explains how Python's __slots__ attribute can dramatically reduce memory usage and speed up attribute access when creating large numbers of objects, providing detailed examples, performance measurements, best‑practice guidelines, and practical use‑case scenarios.
Introduction
Many Python programs suffer from high memory usage when creating large numbers of objects. This article introduces the __slots__ magic attribute that can dramatically reduce memory consumption and speed up attribute access.
Memory Overhead of Regular Classes
By default each instance stores attributes in a __dict__, which adds significant overhead.
class RegularUser:
def __init__(self, name, age, email):
self.name = name
self.age = age
self.email = email
users = [RegularUser(f"user{i}", i % 100, f"user{i}@example.com") for i in range(1000000)]Using __slots__
Defining __slots__ removes the per‑instance __dict__ and fixes the set of attributes.
class SlotsUser:
__slots__ = ['name', 'age', 'email']
def __init__(self, name, age, email):
self.name = name
self.age = age
self.email = emailMemory measurement shows a reduction from ~328 bytes per object to ~96 bytes, a saving of about 70 %.
Performance Test
Attribute access on a slots class is noticeably faster.
def test_access_speed():
regular = RegularUser("test", 25, "[email protected]")
slots = SlotsUser("test", 25, "[email protected]")
# timing loops omitted for brevityWhen to Use __slots__
Creating millions of objects (e.g., game entities, data records).
Memory‑sensitive applications.
Performance‑critical attribute access.
Limitations
Cannot add attributes dynamically.
Inheritance requires careful handling of __slots__.
Incompatible with features that rely on __dict__ (e.g., some decorators, weak references).
Best Practices
Declare all attributes in __slots__.
Use explicit inheritance to extend slots.
Provide clear error messages for illegal attribute assignments.
Example: Game Development
class GameEntity:
__slots__ = ['x', 'y', 'width', 'height', 'health', 'speed', 'texture']
def __init__(self, x, y, width, height):
self.x = x
self.y = y
self.width = width
self.height = height
self.health = 100
self.speed = 1.0
self.texture = NoneCreating 10 000 entities saves roughly 2 MB of memory.
When Not to Use __slots__
When you need to add attributes at runtime.
When using libraries that expect a __dict__.
When the number of objects is small.
During early development when requirements may change.
Python Programming Learning Circle
A global community of Chinese Python developers offering technical articles, columns, original video tutorials, and problem sets. Topics include web full‑stack development, web scraping, data analysis, natural language processing, image processing, machine learning, automated testing, DevOps automation, and big data.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
