__slots__ — это специальный атрибут класса в Python, который позволяет явно объявлять фиксированный набор атрибутов экземпляра, заменяя динамический словарь __dict__ на статический массив дескрипторов.
При обычном создании класса Python использует словарь __dict__ для хранения атрибутов экземпляра, что дает гибкость, но требует памяти. __slots__ оптимизирует это:
class RegularClass:
pass
class SlotsClass:
__slots__ = ['x', 'y']
# Сравнение
regular = RegularClass()
slotted = SlotsClass()
regular.new_attr = 10 # Разрешено
slotted.new_attr = 10 # AttributeError: 'SlotsClass' object has no attribute 'new_attr'
Экономия памяти (основное преимущество)
__dict__, который потребляет больше памяти__slots__ заменяет словарь на фиксированный массив, экономя 40-50% памятиУскорение доступа к атрибутам
Защита от опечаток в именах атрибутов
AttributeErrorПолезен для массовых объектов
Невозможность динамического добавления атрибутов
instance.new_attr = valueПроблемы с наследованием
__slots__, а потомок нет — __dict__ все равно создается__slots__, они объединяютсяНесовместимость с некоторыми инструментами
__dict__pickle требует __getstate__/__setstate__Сложности с weakref
'__weakref__' в __slots__ при необходимостиimport sys
class Regular:
def __init__(self, x, y):
self.x = x
self.y = y
class Slotted:
__slots__ = ['x', 'y']
def __init__(self, x, y):
self.x = x
self.y = y
regular = Regular(1, 2)
slotted = Slotted(1, 2)
print(sys.getsizeof(regular) # Например, 56 (зависит от Python и системы)
print(sys.getsizeof(slotted)) # Например, 48 (экономия памяти)
Можно комбинировать с __dict__ для частичной гибкости:
class Mixed:
__slots__ = ['x', 'y', '__dict__']
def __init__(self, x, y):
self.x = x
self.y = y
m = Mixed(1, 2)
m.x = 10 # Слот
m.z = 30 # __dict__
__slots__ — это оптимизация памяти и производительности__slots__ — мощный инструмент оптимизации, но как любая оптимизация, должен применяться обдуманно и только там, где это действительно необходимо.