Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Apprendre __slots__ vs __dict__ | Writing Memory-Efficient Code
Python Memory Management

__slots__ vs __dict__

Glissez pour afficher le menu

Every Python object stores its instance attributes in a dictionary called __dict__. Dictionaries are flexible but carry significant memory overhead. For classes with a fixed set of attributes – especially when thousands of instances are created – __slots__ replaces __dict__ with a compact fixed-size structure.

The Default: __dict__

By default, every instance of a class gets its own __dict__ that can hold any attribute:

1234567891011121314
import sys # Default class using __dict__ for attribute storage class Transaction: def __init__(self, transaction_id, amount, currency): self.transaction_id = transaction_id self.amount = amount self.currency = currency transaction = Transaction("TX001", 4500.0, "USD") print(transaction.__dict__) # {'transaction_id': 'TX001', 'amount': 4500.0, 'currency': 'USD'} print(sys.getsizeof(transaction)) # Object size – does not include __dict__ overhead print(sys.getsizeof(transaction.__dict__)) # Dict overhead – typically 184+ bytes

The dict overhead is constant per instance regardless of how many attributes are stored.

Using __slots__

Declaring __slots__ tells Python to allocate only the listed attributes – no __dict__ is created:

123456789101112131415
import sys # Class using __slots__ for compact attribute storage class Transaction: __slots__ = ("transaction_id", "amount", "currency") def __init__(self, transaction_id, amount, currency): self.transaction_id = transaction_id self.amount = amount self.currency = currency transaction = Transaction("TX001", 4500.0, "USD") print(sys.getsizeof(transaction)) # Smaller – no __dict__ overhead print(hasattr(transaction, "__dict__")) # False

Measuring the Difference

The savings become significant when many instances are created:

12345678910111213141516171819202122232425262728293031323334
import sys import tracemalloc # Comparing memory usage between __dict__ and __slots__ at scale class RecordWithDict: def __init__(self, record_id, value): self.record_id = record_id self.value = value class RecordWithSlots: __slots__ = ("record_id", "value") def __init__(self, record_id, value): self.record_id = record_id self.value = value tracemalloc.start() records_dict = [RecordWithDict(record_id, record_id * 1.5) for record_id in range(100000)] snapshot_dict = tracemalloc.take_snapshot() del records_dict tracemalloc.clear_traces() records_slots = [RecordWithSlots(record_id, record_id * 1.5) for record_id in range(100000)] snapshot_slots = tracemalloc.take_snapshot() dict_total = sum(s.size for s in snapshot_dict.statistics("lineno")) slots_total = sum(s.size for s in snapshot_slots.statistics("lineno")) print(f"With __dict__: {dict_total / 1024:.1f} KB") print(f"With __slots__: {slots_total / 1024:.1f} KB") tracemalloc.stop()

Limitations of __slots__

__slots__ comes with trade-offs:

  • You cannot add attributes not listed in __slots__ at runtime;
  • Inheritance requires care — subclasses that don't define __slots__ get __dict__ back;
  • Pickling and some dynamic patterns require additional work.

Use __slots__ when:

  • The class has a fixed, known set of attributes;
  • Many instances (thousands or more) will be created;
  • Memory usage is a concern.
question mark

What does defining __slots__ in a class prevent?

Sélectionnez la réponse correcte

Tout était clair ?

Comment pouvons-nous l'améliorer ?

Merci pour vos commentaires !

Section 2. Chapitre 1

Demandez à l'IA

expand

Demandez à l'IA

ChatGPT

Posez n'importe quelle question ou essayez l'une des questions suggérées pour commencer notre discussion

Section 2. Chapitre 1
some-alt