ENIGMA AI
ENIGMA AI

Что такое __slots__ в Python и для чего они используются?

встречается 3× Python middle language_specific

Как ответить

__slots__ — это механизм, который позволяет явно задать атрибуты экземпляра класса, заменяя стандартный словарь __dict__ на более компактную структуру. Основная цель — экономия памяти и ускорение доступа к атрибутам за счёт фиксированной схемы хранения.

Когда ты определяешь __slots__ как кортеж или список имён атрибутов, Python не создаёт для экземпляров __dict__ и __weakref__ (если они не указаны в __slots__). Вместо этого атрибуты хранятся в дескрипторах — каждое имя получает позицию внутри массива C-структуры. Это сильно сокращает накладные расходы: словарь экземпляра занимает ~56 байт пустой, плюс память на сами хэш-таблицы. С __slots__ для, скажем, класса с двумя атрибутами каждый экземпляр будет весить около 24 байт вместо 56+. Разница становится заметной на тысячах или миллионах объектов.

Обратная сторона — гибкость теряется: нельзя добавлять новые атрибуты динамически (кроме случаев, когда __dict__ явно включён в __slots__). Также нельзя наследовать __slots__ «автоматически» — если подкласс не объявит свои __slots__, он вернётся к __dict__. При множественном наследовании нужно помнить про коллизии имён (что один слот может быть объявлен в нескольких родителях).

Пример использования:

class Point:
    __slots__ = ('x', 'y')

    def __init__(self, x, y):
        self.x = x
        self.y = y

p = Point(1, 2)
print(p.x)  # 1
# p.z = 3   # AttributeError: 'Point' object has no attribute 'z'
print(p.__slots__)  # ('x', 'y')
# print(p.__dict__) # AttributeError

Я использую __slots__ в проектах, где есть множество мелких объектов — например, узлы графа, точки в 3D, лёгкие DTO для сериализации. Но не стоит применять «на всякий случай»: если класс всё равно будет иметь __dict__ (из-за наследования или явного включения), выигрыш исчезает. Лучше профилировать.

Ключевые тезисы

  • __slots__ заменяет __dict__ экземпляра на фиксированный массив, экономя память и ускоряя доступ к атрибутам
  • Атрибуты должны быть объявлены заранее — динамическое добавление невозможно (если не добавить __dict__ в слоты)
  • При наследовании __slots__ не наследуются автоматически — подкласс должен объявить свои слоты, иначе вернётся __dict__
  • Хорошо подходит для классов с большим количеством экземпляров (например, игровые объекты, математические векторы, DTO)
  • Не стоит использовать без профилирования: накладные расходы на дескрипторы могут перевесить выгоду, если экземпляров мало или у класса сложное наследование

Что спросят дальше

  • — Как поведёт себя __slots__ при множественном наследовании и коллизии имён?
  • — Можно ли сохранить слабые ссылки (weak references) на объекты со __slots__?
  • — Как работает __slots__ в сочетании с дескрипторами (property, классовые атрибуты)?

Готовьтесь к собеседованию с ENIGMA AI

AI-суфлёр подсказывает ответы прямо на собеседовании в реальном времени — незаметно для интервьюера.

Скачать приложение