ProgrammingBackend Python Developer

What is __slots__ in Python classes, why are they needed, and what are their limitations?

Pass interviews with Hintsage AI assistant

Answer.

__slots__ is a special class attribute that limits the set of allowed instance attributes, saves memory, and speeds up attribute access. Using __slots__ is especially relevant for a large number of similar objects.

History of the issue:

The appearance of __slots__ is related to the fact that by default, each Python object instance has an attribute dictionary (__dict__), which is convenient but memory-intensive. For a million objects with a small set of fields, there is significant overhead.

Problem:

Instances of a regular class can dynamically expand, which is convenient but inefficient. Applying __slots__ limits the dynamic addition of new attributes, removes the instance attribute dictionary, saves memory, and speeds up access.

Solution:

Describe the list of allowed fields in the __slots__ attribute:

class Point: __slots__ = ('x', 'y') def __init__(self, x, y): self.x = x self.y = y p = Point(1, 2) p.z = 3 # AttributeError: 'Point' object has no attribute 'z'

Key features:

  • Saves memory by omitting dict and weakref by default.
  • Defines a strict set of allowed fields.
  • Allows for faster access to attributes thanks to pre-allocated slots (does not require searching in dict).

Trick questions.

Can you create an instance of a class with slots and then add an attribute not from the list?

No. Attempting to add an attribute not in the slots list will raise an AttributeError. This places limitations on the extensibility of the object.

Can you inherit from a class with slots and add new fields?

Yes, but each subclass must declare its own slots. In this case, parent and current slots are combined. However, if slots are not declared in the subclass, the descendant will have dict again!

Does slots work for immutable types?

Yes, but additional measures must be implemented to make the slot object immutable (for example, via property without a setter).

Typical mistakes and anti-patterns

  • Not declaring slots in the child class, breaking memory efficiency.
  • Expecting slots to work in the presence of multiple inheritance — conflicts and errors may arise.
  • Attempting to serialize objects with slots using standard means can sometimes be complicated (for example, pickle requires dict).

Real-life example

Negative case

A regular class for a point:

class Point: def __init__(self, x, y): self.x = x self.y = y points = [Point(i, i) for i in range(1_000_000)]

Pros:

  • Flexible — you can add any attributes.
  • Easy to understand for beginners.

Cons:

  • The task manager shows significantly inflated memory consumption (up to +20-30%).

Positive case

An analogous class but with slots:

class Point: __slots__ = ('x', 'y') def __init__(self, x, y): self.x = x self.y = y points = [Point(i, i) for i in range(1_000_000)]

Pros:

  • Up to 30% memory savings on millions of objects.
  • Faster access to fields.

Cons:

  • Objects become inflexible: new attributes cannot be added on-the-fly.