len, [], for, + ne sont pas des primitives — ce sont des appels de dunders.len, [], for, + aren't primitives — they're dunder calls.
Le numéro précédent parlait des méthodes que tu nommes : source.read(). Voici l'autre moitié du protocole, la plus puissante — les méthodes que Python appelle pour toi, sans que tu les écrives explicitement. len(p) n'est pas une fonction qui radiographie p : c'est un raccourci pour p.__len__(). De même x[k] appelle __getitem__, a + b appelle __add__, for … in x appelle __iter__. Ces méthodes à double underscore — les « dunders » — sont les points d'ancrage du modèle de données. Les implémenter, c'est brancher ton objet directement sur la syntaxe du langage.The previous issue was about methods you name: source.read(). Here's the other half of the protocol, the more powerful one — the methods Python calls for you, without you writing them explicitly. len(p) isn't a function that X-rays p: it's shorthand for p.__len__(). Likewise x[k] calls __getitem__, a + b calls __add__, for … in x calls __iter__. These double-underscore methods — the 'dunders' — are the data model's anchor points. Implementing them wires your object straight into the language's syntax.
class Panier: def __init__(self, articles): self.articles = articles def __len__(self): # une méthode « spéciale » return len(self.articles) p = Panier(["pomme", "pain"]) print(len(p)) # 2 — len(p) n'a pas inspecté p : il a appelé p.__len__() if p: # « le panier est-il non vide ? » print("non vide") # vrai — sans __bool__, Python retombe sur __len__
Chaque bout de syntaxe « magique » de Python est, en dessous, un appel à une méthode que tu peux définir. Le langage ne réserve pas ces pouvoirs à ses types natifs — il te donne les mêmes crochets.Every piece of Python's "magic" syntax is, underneath, a call to a method you can define. The language doesn't reserve these powers for its native types — it hands you the same hooks.
Quand tu veux qu'un objet « se comporte comme » une liste, un nombre, un fichier, ne cherche pas une classe de base à hériter. Demande : quelle syntaxe dois-je supporter, et quel dunder chaque syntaxe appelle-t-elle ? Implémente ces dunders, et l'objet parle nativement la langue.When you want an object to "behave like" a list, a number, a file, don't look for a base class to inherit. Ask: which syntax must I support, and which dunder does each syntax call? Implement those dunders, and the object speaks the language natively.
Dans un langage nominal, « être une séquence » veut dire hériter d'une interface Sequence. En Python, ça veut dire répondre à __len__ et __getitem__. La liste, la chaîne, le tuple ne partagent pas une classe de base commune riche : ils partagent un jeu de dunders. Ton objet entre dans la même famille par les mêmes méthodes, sans lien de parenté.In a nominal language, 'being a sequence' means inheriting a Sequence interface. In Python, it means answering __len__ and __getitem__. The list, the string, the tuple don't share a rich common base class: they share a set of dunders. Your object joins the same family through the same methods, with no kinship.