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

__slots__ vs __dict__

Scorri per mostrare il 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?

Seleziona la risposta corretta

Tutto è chiaro?

Come possiamo migliorarlo?

Grazie per i tuoi commenti!

Sezione 2. Capitolo 1

Chieda ad AI

expand

Chieda ad AI

ChatGPT

Chieda pure quello che desidera o provi una delle domande suggerite per iniziare la nostra conversazione

Sezione 2. Capitolo 1
some-alt