Vol. 6 — № 18
The Python Loop · KiosqueNewsstand
Blog  
Un atelier Python · Édition d'ApprentissageA Python Workshop · Learning Edition

__slots__ : le __dict__ a un coût __slots__: the __dict__ has a cost

Chaque instance porte, par défaut, son propre __dict__ — une table de hachage complète, allouée dynamiquement, prête à accueillir n'importe quel attribut à n'importe quel moment. Ce confort a un prix en mémoire, multiplié par chaque objet créé. __slots__ le supprime : les attributs deviennent des descripteurs à taille fixe. La mémoire économisée se paie en flexibilité perdue. Every instance carries, by default, its own __dict__ — a full hash table, dynamically allocated, ready to welcome any attribute at any moment. That comfort has a memory price, multiplied by every object created. __slots__ removes it: attributes become fixed-size descriptors. The memory saved is paid for in lost flexibility.

AudienceAudience
Dev qui a ajouté __slots__ à une classe et vu une AttributeError surgir sur un attribut qui marchait la veille Dev who added __slots__ to a class and watched an AttributeError appear on an attribute that worked yesterday
Format
Self-paced
ChapitresChapters
5
Date
Juil 2026 Jul 2026
≈ 18 min ●●●● __slots__MémoireDescripteurs

Chapitre 1 en accès libre — la suite (ch. 2 à 5) est réservée. Chapter 1 free to read — the rest (ch. 2–5) is members-only.

01CadrageFraming3 min

Le mot de l'éditeur précédent posait la question : combien coûte ce __dict__ que chaque instance porte, sans qu'on l'ait demandé ?The previous editorial's note posed the question: how much does that __dict__ every instance carries, unasked, actually cost?

Les numéros 16 et 17 ont supposé, sans jamais le questionner, qu'une instance porte un __dict__ — un dictionnaire ordinaire, capable d'accueillir n'importe quel attribut, à n'importe quel moment de la vie de l'objet. C'est ce confort qui permet self.nouvel_attribut = valeur sans jamais déclarer nouvel_attribut à l'avance. Ce confort a un coût mesurable : un dictionnaire alloué dynamiquement, avec sa table de hachage, ses collisions possibles, sa capacité qui grandit par paliers — même pour une classe aussi simple qu'un point à deux coordonnées, fixées une fois pour toutes dans __init__ et jamais renommées. Depuis Python 3.11, CPython retarde la construction de ce dictionnaire tant que personne ne le demande : le coût a fondu, il n'a pas disparu.Issues 16 and 17 both assumed, without ever questioning it, that an instance carries a __dict__ — an ordinary dictionary, able to welcome any attribute, at any point in the object's life. That comfort is what lets self.new_attribute = value work without ever declaring new_attribute ahead of time. That comfort has a measurable cost: a dynamically allocated dictionary, with its hash table, its possible collisions, its capacity growing in steps — even for a class as simple as a two-coordinate point, fixed once and for all in __init__ and never renamed. Since Python 3.11, CPython delays building that dictionary until someone asks for it: the cost has shrunk, not vanished.

Chaque instance reste prête à devenir un dictionnaire — et le paieEvery instance stays ready to become a dictionary — and pays for it
class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

p = Point(1, 2)
print(p.__dict__)    # {'x': 1, 'y': 2} -- un vrai dict, fabriqué à la demande

# depuis Python 3.11, CPython range x et y directement dans l'objet et ne
# construit ce dictionnaire que si on le réclame (comme ci-dessus) --
# mais chaque instance reste prête à accueillir n'importe quel nom,
# alors que Point n'en utilise que 2, toujours les mêmes, fixés dès __init__.
# Le coût réel se mesure au chapitre 3.
Le sous-réflexe du numéroThis issue's sub-reflex

Face à une classe qui crée des milliers d'instances aux attributs fixes et connus d'avance, demande : ai-je vraiment besoin qu'on puisse ajouter n'importe quel attribut, n'importe quand — ou est-ce que je paie pour une flexibilité que je n'utilise jamais ?Facing a class that creates thousands of instances with fixed, known-in-advance attributes, ask: do I really need the ability to add any attribute, at any time — or am I paying for flexibility I never use?

Un coût qui ne se voit que multipliéA cost only visible once multiplied

Une quarantaine d'octets par instance ne pèsent rien pour un objet unique. Multipliés par un million d'instances — un parseur, un jeu de données, une simulation — la différence se compte en dizaines de mégaoctets, davantage si le __dict__ finit par être matérialisé.Forty-odd bytes per instance weigh nothing for a single object. Multiplied by a million instances — a parser, a dataset, a simulation — the difference adds up to tens of megabytes, more if the __dict__ ends up materialized.

🔒

La suite est réservée The rest is members-only

Le premier numéro est libre. Débloque tout The Python Loop — tous les volumes, à vie — pour 5 €, paiement unique. The first issue is free. Unlock all of The Python Loop — every volume, forever — for €5, one-time.

Retour au kiosqueBack to newsstand