What is __slots__ and why is it needed

онлайн тренажер по питону
Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

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.

News