__slots__
Меньше памяти, быстрее доступ.
__slots__ — заранее объявленный список атрибутов
Обычный класс хранит атрибуты экземпляра в __dict__ — это словарь, занимающий ~100+ байт даже для пары полей. Если у тебя миллионы маленьких объектов (точки, узлы графа, события), эти словари съедают мегабайты. __slots__ говорит Python: «у этих экземпляров есть только эти атрибуты», и интерпретатор кладёт их в фиксированные слоты в C-структуре — без __dict__, без __weakref__.
Что это даёт
- Память: на простых классах экономия 40-60%.
- Скорость доступа: на ~20% быстрее __dict__-варианта (прямой offset вместо хеш-лукапа).
- Защита от опечаток: p.naem = 1 поднимет AttributeError, а не молча создаст новый атрибут.
Как читается
class Point:
__slots__ = ("x", "y")
def __init__(self, x, y):
self.x, self.y = x, y
p = Point(1, 2)
p.z = 3 # AttributeError: 'Point' object has no attribute 'z'
Пример: реальная экономия
import sys
class A: # с __dict__
def __init__(self):
self.x = 0; self.y = 0
class B:
__slots__ = ("x", "y")
def __init__(self):
self.x = 0; self.y = 0
print(sys.getsizeof(A().__dict__)) # ~104
у B нет __dict__ вообще — атрибуты лежат прямо в объекте
Когда использовать / подводные камни
👍 Hot-path структуры данных, парсеры (узлы AST), геометрия, телеметрия, миллионы DTO.
👎 Ломает совместимость со многими миксинами (которые ожидают __dict__), мешает динамически добавлять атрибуты (что бывает нужно в тестах/моках). При наследовании все базы должны определять __slots__, иначе __dict__ всё равно появится. В обычном бизнес-коде выгода ничтожна — не используй преждевременно.