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

LEGB : la résolution des noms LEGB: name resolution

Lire un nom dans une fonction cherche dans quatre portées, dans un ordre fixe : Local, Enclosing, Global, Built-in. Mais Python décide si un nom est local avant même d'exécuter la moindre ligne — en scannant tout le corps de la fonction à la recherche d'une assignation. Le résultat : lire une variable avant de l'assigner, plus bas dans la même fonction, ne va pas chercher la variable globale du même nom. Ça lève une UnboundLocalError. Reading a name inside a function searches four scopes, in a fixed order: Local, Enclosing, Global, Built-in. But Python decides whether a name is local before running a single line — by scanning the whole function body for an assignment. The result: reading a variable before assigning it, further down in the same function, doesn't fall back to the global variable of the same name. It raises UnboundLocalError.

AudienceAudience
Dev qui a vu une UnboundLocalError sur une variable qui existe pourtant, plus haut, en global Dev who's hit UnboundLocalError on a variable that clearly exists, higher up, as a global
Format
Self-paced
ChapitresChapters
5
Date
Juil 2026 Jul 2026
≈ 18 min ●●○○ PortéeLEGBScoping

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

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.

Les quatre portées, dans leur ordre de rechercheThe four scopes, in search order
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
Le sous-réflexe du numéroThis issue's sub-reflex

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'ordre n'est pas négociableThe order isn't negotiable

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.

🔒

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