Ответ
Атрибут класса __slots__
используется для оптимизации потребления памяти и ускорения доступа к атрибутам экземпляров. Он позволяет явно указать, какие атрибуты может иметь объект, отказываясь от стандартного механизма хранения атрибутов в словаре __dict__
.
Как это работает?
По умолчанию каждый экземпляр класса в Python имеет специальный атрибут __dict__
, который представляет собой словарь для хранения его атрибутов. Это гибко, но затратно по памяти.
__slots__
заменяет __dict__
на более компактную структуру данных (похожую на кортеж), где для каждого атрибута зарезервирована ячейка.
Основные преимущества:
- Экономия памяти: Особенно заметна при создании тысяч или миллионов экземпляров небольших объектов.
- Ускорение доступа: Доступ к атрибутам через
__slots__
происходит быстрее, чем поиск ключа в словаре__dict__
.
Пример:
class Point:
# Определяем фиксированный набор атрибутов
__slots__ = ('x', 'y')
def __init__(self, x, y):
self.x = x
self.y = y
# Создаем экземпляр
p = Point(10, 20)
# Доступ к атрибутам работает как обычно
print(f"Координаты: {p.x}, {p.y}")
# Попытка добавить новый атрибут вызовет ошибку
try:
p.z = 30
except AttributeError as e:
print(f"Ошибка: {e}")
# Вывод: Ошибка: 'Point' object has no attribute 'z'
# У объекта отсутствует __dict__
print(hasattr(p, '__dict__')) # False
Ограничения и недостатки:
- Отсутствие гибкости: Нельзя динамически добавлять новые атрибуты в экземпляр.
- Сложности с наследованием: Если дочерний класс не определяет
__slots__
, у его экземпляров появится__dict__
. Если и родитель, и потомок определяют__slots__
, то набор атрибутов потомка будет объединением.
Когда использовать __slots__
?
Используйте __slots__
в качестве оптимизации в приложениях, где создается огромное количество экземпляров одного класса, и потребление памяти становится критичным фактором. Это не должно быть стандартной практикой для всех классов.