TGViewer
About Python [ru] About Python [ru] @python_tesst · 6.45K subscribers
Post #2834 317
⁣Память под контролем: __slots__, pympler и гибридные модели

Про __slots__ пишут часто, но в реальных проектах с сотнями классов можно нарваться. Не всё так радужно.

Оверхед словаря и мифы

По умолчанию каждый экземпляр держит атрибуты в __dict__. Словарь с хеш-таблицей для миллионов объектов - это 50-70% оверхеда. __slots__ фиксирует список атрибутов на уровне класса и убирает __dict__ (если не добавить вручную). Экономия до 40-60%. Но в больших кодовых базах всплывают грабли:
- наследование: у родителя нет __slots__, у наследника есть - __dict__ все равно создается, выигрыша нет
- жесткость: нельзя динамически добавить атрибут - ломаются ORM, сериализаторы, половина библиотек
- дебаг: без __dict__ не увидишь текущие поля экземпляра в отладчике, приходится лезть в класс

Профилирование через pympler

Вместо гаданий - профилирование через pympler. Пример:

from pympler import asizeof

class WithSlots:
__slots__ = ('x', 'y')
def __init__(self):
self.x = 10
self.y = 20

class WithoutSlots:
def __init__(self):
self.x = 10
self.y = 20

print(asizeof.asizeof(WithSlots())) # ~72 байта
print(asizeof.asizeof(WithoutSlots())) # ~184 байта


Цифры не врут: видно, где оверхед реально критичен, а где можно забить.

Гибридная модель: __slots__ + __dict__

Когда часть объектов динамическая (dataclass с optional полями), добавляем __dict__ в __slots__:

class FlexibleSlots:
__slots__ = ('id', 'name', '__dict__')
def __init__(self, id, name, **kwargs):
self.id = id
self.name = name
for k, v in kwargs.items():
setattr(self, k, v)

obj = FlexibleSlots(1, 'test', extra_field=42)
print(obj.extra_field) # 42


Жесткие поля - без оверхеда словаря, динамические - через __dict__. Памяти чуть больше, но гибкость остается.

Что я обычно делаю:
- профилирую не на старте, а когда память реально начинает течь (pympler.muppy, pympler.summary)
- для тысяч объектов - ORM-модели, объекты игр - обязательно __slots__
- если dataclass с наследованием - @dataclass(slots=True) (Python 3.10+), но контролирую дерево наследования
- никогда не пихаю __slots__ в классы, которые подмешиваются через MRO или передаются в гибкие фреймворки

Вывод: __slots__ - мощный инструмент для сокращения памяти, но его применение требует профилирования и осознанного проектирования, особенно при наследовании и в гибридных сценариях с __dict__.
  • ❤ 1
More from @python_tesst
  1. Sep 28, 2026Post #3191
  2. Sep 27, 2026OpenAI метит в подписку за 500 баксов Что там в описании тарифа? Пока что от ChatGPT Pro о…
  3. Sep 27, 2026Post #3189
  4. Sep 27, 2026Свежая обложка The Economist подъехала Журналисты: да мы вообще не сгущаем краски Те же жу…
  5. Sep 27, 2026Ночная годнота: Docker выкатила первые официальные скиллы для ИИ-агентов, которые ковыряют…
  6. Sep 27, 2026Post #3186
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →