Règle LEGB — c'est la règle de recherche des espaces de noms (scoping) en Python. L'acronyme se décompose comme suit :
len, list, etc.).Lorsque Python rencontre une variable, il cherche d'abord localement, puis dans les fonctions englobantes, ensuite dans l'espace global du module, et enfin dans l'espace des objets intégrés :
def outer(): x = 'enclosing' def inner(): x = 'local' print(x) inner() outer() # 'local'
Si à l'intérieur de inner() on supprime l'assignation de x, Python prendra x de l'espace englobant (outer). S'il n'y a pas de variable là non plus, il cherche globalement, puis dans les intégrés.
Comment se comportera la fonction si vous oubliez de déclarer
nonlocalougloballors de la modification d'une variable d'un niveau supérieur ?
Réponse :
Si vous essayez de modifier une variable de l'espace d'un niveau supérieur à l'intérieur d'une fonction imbriquée sans déclarer nonlocal (ou global — si la variable est au niveau du module), Python créera une nouvelle variable locale, sans modifier l'extérieur.
Exemple :
x = 10 def foo(): x = 20 # Ceci est un nouveau x local, le global ne change pas foo() print(x) # 10
Pour modifier le x global :
def foo(): global x x = 20
Avec des variables dans la fonction englobante — utilisez nonlocal.
Histoire 1
Dans un projet éducatif, des fonctions imbriquées ont été utilisées pour compter le nombre d'appels. Le développeur a écrit :
def counter(): count = 0 def inc(): count += 1 return count return inc
Mais cela a entraîné un UnboundLocalError, car count à l'intérieur de inc() était considéré comme nouveau (un count local était créé). Solution : déclarer count nonlocal.
Histoire 2
Dans une application web, ils voulaient modifier le cache global dans le gestionnaire :
cache = {} def add_to_cache(key, value): cache[key] = value
Cependant, si on avait essayé de réécrire complètement le cache à l'intérieur de la fonction, par exemple cache = {key: value}, cela aurait créé un nouveau cache local, sans lien avec le global, en raison de l'absence de global cache.
Histoire 3
Dans un grand système ETL, un bogue a été rencontré : les programmeurs ont laissé la variable result sans initialisation explicite à l'intérieur de la fonction, espérant qu'elle se prendrait de l'espace externe. Mais après quelques itérations, le résultat a commencé à être décalé, car à l'intérieur il y avait une écriture result += value, et non result = result + value (sans nonlocal/global) — et result était réinitialisé à chaque appel.