What is __slots__ and Why Do You Need It? The Ultimate Guide to Optimizing Classes in Python
In Python, classes play a key role in object-oriented programming. However, when actively working with objects, you may have noticed that such programs can consume a significant amount of memory. This becomes especially critical when creating millions of instances of the same class.
In such cases, a special mechanism comes to the rescue - __slots__. This is not just a syntactic element, but a powerful optimization tool that allows you to control memory and speed up programs.
Let's figure out what __slots__ is, how to use it, and in what situations it is really needed.
What is __slots__ in Python?
__slots__ is a special class attribute that restricts the list of allowed attributes for instances of that class.
By default, when creating objects in Python, their attributes are stored in the __dict__ dictionary. This is convenient, but inefficient in terms of memory, especially if many objects of the same type are created.
When you define __slots__, Python, instead of using a dictionary, creates statically allocated structures to store attributes, which significantly saves memory and speeds up access to these attributes.
? Simple Example without using __slots__:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
p = Person("Alice", 30)
print(p.__dict__) # {'name': 'Alice', 'age': 30}
As you can see, all attributes are stored in __dict__.
? Now an example using __slots__:
class Person:
__slots__ = ['name', 'age']
def __init__(self, name, age):
self.name = name
self.age = age
p = Person("Alice", 30)
print(p.name) # Alice
Let's try adding a new attribute:
p.city = "New York" # AttributeError: 'Person' object has no attribute 'city'
✅ Conclusion: Now the Person object is strictly limited to only the name and age attributes.
Why Use __slots__?
-
Memory saving:
Using
__slots__significantly reduces memory consumption, since space is not allocated for the attribute dictionary. -
Speeding up access to attributes:
Accessing and setting attributes becomes faster due to the statically defined data structure.
-
Limiting the structure of the object:
This helps to avoid accidentally adding unwanted attributes and makes the class structure more strict.
Comparing memory: with __slots__ and without it
import sys
class WithDict:
def __init__(self):
self.x = 1
self.y = 2
class WithSlots:
__slots__ = ['x', 'y']
def __init__(self):
self.x = 1
self.y = 2
obj1 = WithDict()
obj2 = WithSlots()
print(sys.getsizeof(obj1)) # Approximately 56-64 bytes
print(sys.getsizeof(obj2)) # Approximately 48 bytes
✅ Conclusion: Memory saving is obvious, especially when creating many objects.
Limitations of using __slots__
Although __slots__ is useful, it is important to remember its limitations:
- You cannot add new attributes that are not specified in
__slots__. - Instances will not have the
__dict__attribute (unless you explicitly add it to__slots__). - Cannot be used with multiple inheritance if base classes use different
__slots__. - Objects with
__slots__do not support weak references unless you specify'__weakref__'in__slots__.
? How to allow weak references:
class Person:
__slots__ = ['name', '__weakref__']
def __init__(self, name):
self.name = name
Can I Inherit Classes with __slots__?
Yes, but with certain features. If the base class uses __slots__, then in the descendant you need to either redefine __slots__ or leave it empty.
class Base:
__slots__ = ['x']
class Child(Base):
__slots__ = ['y']
obj = Child()
obj.x = 10
obj.y = 20
✅ Important: If __slots__ is not defined in one of the classes, the optimization will not work.
When should I use __slots__ and when not?
| Scenario | Recommendation |
|---|---|
| Many objects of the same type | Use __slots__ |
| Small projects and scripts | You can do without it |
| Dynamic addition of attributes required | Do not use __slots__ |
| Memory saving is critical | Use __slots__ |
FAQ - Frequently Asked Questions
❓ 1. Can I specify a variable instead of a list of strings in __slots__?
No, __slots__ must be either a string or an iterable object of strings.
❓ 2. How to add attributes to an existing class with __slots__?
This is not possible without modifying the original class. You need to foresee all the attributes in __slots__ in advance.
❓ 3. Can I use __slots__ with dataclass?
Yes, starting with Python 3.10, you can use the slots=True parameter:
from dataclasses import dataclass
@dataclass(slots=True)
class Point:
x: int
y: int
❓ 4. Can I delete attributes defined in __slots__?
Yes, using the del function:
p = Person("Alice", 30)
del p.name
❓ 5. How to see if an object has __slots__?
Use:
print(hasattr(object, '__slots__'))
❓ 6. Is using __slots__ in production code a good practice?
Yes, if your project involves a large number of objects and performance is important. However, you need to take into account all the limitations and plan the class structure in advance.
Conclusion
Using __slots__ is a powerful way to optimize memory and performance in Python. However, it should be applied consciously, understanding all the pros and cons.
If you have millions of objects of the same type in your project and saving resources is critical - __slots__ will help significantly improve performance. In other cases, this is more of a tool for improving discipline and code structure.
The Future of AI in Mathematics and Everyday Life: How Intelligent Agents Are Already Changing the Game
Experts warned about the risks of fake charity with AI
In Russia, universal AI-agent for robots and industrial processes was developed