← Назад к вопросам

На что влияет атрибут __slots__?

2.0 Middle🔥 181 комментариев
#Python Core#Архитектура и паттерны

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

На что влияет атрибут slots?

Атрибут __slots__ влияет на использование памяти и производительность экземпляров класса. Он ограничивает какие атрибуты может иметь объект класса, удаляет динамический словарь __dict__ и экономит оперативную память.

Как это работает

По умолчанию Python хранит атрибуты экземпляра в словаре __dict__:

# ❌ БЕЗ __slots__
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

person = Person("Alice", 30)
print(person.__dict__)  # {name: Alice, age: 30}

# Можно добавить любой атрибут динамически
person.email = "alice@example.com"  # Работает
person.phone = "+1234567890"  # Работает

Словари требуют дополнительной памяти для хранения хешей и указателей. Если создать миллионы объектов, это будет значительный оверхед.

С использованием slots

Этот атрибут явно определяет какие поля может иметь класс:

# ✅ С __slots__
class Person:
    __slots__ = (name, age)
    
    def __init__(self, name, age):
        self.name = name
        self.age = age

person = Person("Alice", 30)
print(hasattr(person, __dict__))  # False — нет __dict__

# Динамическое добавление теперь невозможно
person.email = "alice@example.com"  # AttributeError: Person object has no attribute email

Сравнение памяти

import sys

class PersonWithoutSlots:
    def __init__(self, name, age):
        self.name = name
        self.age = age

class PersonWithSlots:
    __slots__ = (name, age)
    
    def __init__(self, name, age):
        self.name = name
        self.age = age

# Размер объекта
obj1 = PersonWithoutSlots("Alice", 30)
obj2 = PersonWithSlots("Alice", 30)

print(f"Без __slots__: {sys.getsizeof(obj1)} байт")  # ~296 байт
print(f"С __slots__: {sys.getsizeof(obj2)} байт")    # ~56 байт

# Для 1 000 000 объектов разница будет существенной

Преимущества slots

  • Экономия памяти (в 5-10 раз для большого количества объектов)
  • Быстрее доступ к атрибутам (нет хеширования словаря)
  • Защита от опечаток (нельзя добавить произвольный атрибут)
  • Лучшая производительность в многопоточных приложениях

Недостатки slots

  • Меньше гибкости — нельзя добавлять новые атрибуты
  • Сложнее наследование — нужно определять slots в каждом подклассе
  • Проблемы с примесями (mixins) — может потребоваться __dict__ в миксине
  • Сложнее отладка — некоторые фреймворки требуют __dict__
# Наследование с __slots__
class Employee(Person):
    __slots__ = (salary,)  # Дополнительное поле
    
    def __init__(self, name, age, salary):
        super().__init__(name, age)
        self.salary = salary

Когда использовать slots

  • Когда нужно хранить миллионы объектов (например, в NumPy массивах)
  • Когда критична производительность (обработка больших данных)
  • Когда нужно защитить интерфейс класса от случайных изменений
  • В структурах данных, где не нужна динамичность

Современный подход: dataclass

В Python 3.10+ можно использовать dataclass с slots=True:

from dataclasses import dataclass

@dataclass(slots=True)
class Person:
    name: str
    age: int

person = Person("Alice", 30)

Это совмещает удобство dataclass с эффективностью slots.

Заключение

__slots__ — это оптимизация памяти и производительности. Используй его когда нужна эффективность, но помни о потере гибкости.

На что влияет атрибут __slots__? | PrepBro