Зачем нужен атрибут класса __slots__?

По умолчанию Python хранит атрибуты объекта в словаре под названием __dict__. Словари, в свою очередь, представляют собой хеш-таблицы с открытой адресацией, которые ещё и расширяются при заполнении на ⅔. Такая конструкция даёт быстрый доступ к значению по ключу, но влечёт накладные расходы по занимаемой памяти.

Тогда получается, что могут возникнуть проблемы, если появится необходимость наплодить миллионы объектов какого-то типа. Тут на помощь приходит атрибут класса __slots__. Это “указание” интерпретатору на то, что атрибуты объектов класса, перечисленные в __slots__, нужно хранить в кортеже, а не словаре (важный нюанс: __slots__ учитывается для каждого класса индивидуально и не наследуется).

При этом объекты класса не смогут иметь какие-то другие атрибуты, кроме указанных в __slots__. Стоит отметить, что данное свойство является побочным эффектом и не рекомендуется в качестве средства ограничения функциональности объектов класса.

Интересно, что в __slots__ можно указать атрибут __dict__ и, таким образом, получить назад возможность динамически добавлять атрибуты, но это может свести на нет пользу от оптимизации потребления памяти.

Именно поэтому прежде чем использовать в своем классе __slots__, обязательно стоит вспомнить классическое высказывание Дональда Кнута: «Преждевременная оптимизация — корень всех зол» — и подумать ещё раз.