Un nom lu n'est jamais résolu au hasard — il traverse quatre portées, dans un ordre fixe.A name read is never resolved at random — it walks four scopes, in a fixed order.
Le Vol. I a posé la question de la liaison : à quel objet un nom est-il lié. Ce volume la rouvre sous un angle différent — non plus quel objet, mais quand et où ce nom est cherché. Quand Python rencontre un nom à l'intérieur d'une fonction, il ne le cherche pas n'importe où : il consulte quatre portées, dans un ordre strict — Local (la fonction elle-même), Enclosing (les fonctions englobantes), Global (le module), Built-in (print, len, et le reste). Il s'arrête à la première portée où le nom existe, sans continuer plus loin.Vol. I raised the question of binding: which object a name is bound to. This volume reopens it from a different angle — not which object, but when and where that name is looked up. When Python encounters a name inside a function, it doesn't search just anywhere: it consults four scopes, in strict order — Local (the function itself), Enclosing (the enclosing functions), Global (the module), Built-in (print, len, and the rest). It stops at the first scope where the name exists, without looking further.
x = "globale" # portée Global def externe(): x = "englobante" # portée Enclosing (vue depuis interne) def interne(): x = "locale" # portée Local print(x) # 'locale' -> trouvé en L, s'arrête là interne() externe() def sans_local(): x = "englobante" def interne(): print(x) # pas de x en L -> cherche en E -> 'englobante' interne() sans_local() print(len([1, 2])) # len : ni L, ni E, ni G -> Built-in
Face à un nom lu dans une fonction, demande : où, dans les quatre portées, ce nom existe-t-il en premier ? Pas « où pourrait-il exister » — la première portée qui le contient gagne, et les autres ne sont jamais consultées.Facing a name read inside a function, ask: in which of the four scopes does this name exist first? Not "where could it exist" — the first scope that holds it wins, and the others are never consulted.
L, puis E, puis G, puis B — jamais dans un autre sens, jamais en parallèle. Un nom local masque toujours un nom global du même nom ; un built-in redéfini en global (écraser list, par exemple) masque le built-in partout dans le module.L, then E, then G, then B — never the other way, never in parallel. A local name always shadows a global name of the same name; a built-in redefined as a global (shadowing list, for instance) hides the built-in everywhere in the module.