Получить доступ

Что такое __slots__ и когда его использовать?

MiddleВнутреннее устройство
Ещё спрашивают так:
  • Как уменьшить память под миллион объектов в Python?
Коротко

__slots__ = ("x", "y") заменяет у экземпляров словарь __dict__ на фиксированные ячейки: объект занимает в несколько раз меньше памяти, доступ к атрибутам чуть быстрее, а добавить новый атрибут нельзя (AttributeError).

  • Выигрыш заметен на миллионах мелких объектов
  • Наследники без своих __slots__ снова получают __dict__
  • Для weakref нужно добавить '__weakref__' в слоты

А ещё @dataclass(slots=True) с Python 3.10 генерирует слоты сам

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

Без слотов каждый экземпляр хранит атрибуты в своём словаре — гибко, но словарь на каждый объект стоит сотни байт.

class Point:
    __slots__ = ("x", "y")
    def __init__(self, x, y):
        self.x, self.y = x, y

p = Point(1, 2)
p.z = 3      # AttributeError

Слоты реализованы дескрипторами на уровне класса: каждый атрибут — ячейка фиксированного смещения в объекте.

Ограничения:

  • нельзя добавлять атрибуты, не перечисленные в слотах;
  • множественное наследование от двух классов с непустыми слотами невозможно;
  • значения по умолчанию через атрибуты класса конфликтуют со слотами;
  • pickle и копирование работают, но старые библиотеки, ожидающие __dict__, могут сломаться.

Когда применять: много мелких объектов (точки, узлы графа, записи из парсера). Для обычных бизнес-объектов выигрыш не нужен.

Что хотят услышать

  • Что заменяют слоты и выигрыш в памяти.
  • Ограничения.
  • dataclass(slots=True).

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем