La portée (scope) d'une variable est le contexte dans lequel elle est accessible. En Python, il existe 4 portées principales que l'on peut retenir selon le principe LEGB :
Le mot-clé global permet de modifier une variable déclarée au niveau global depuis l'intérieur d'une fonction.
def foo(): global my_var my_var = 10 # modifie la variable globale
Sans global, à l'intérieur de la fonction, la variable est considérée comme locale, même si un tel nom existe dans la portée externe.
"Que va afficher le code suivant ?"
x = 10 def func(): x = 20 func() print(x)
Réponse :
Affichera 10, car à l'intérieur de la fonction une nouvelle variable locale x est créée, la variable globale n'est pas modifiée.
Histoire
Dans le gestionnaire de commandes du bot, il voulait stocker un compteur global, mais a oublié de spécifier global :
counter = 0 def increment(): counter += 1 # UnboundLocalError : la variable locale 'counter' référencée avant l'affectation
L'erreur provient du fait que l'interpréteur considère counter comme une variable locale (puisqu'elle est assignée au cours de la fonction), et non pas comme globale.
Histoire
Dans des fonctions imbriquées, ils ont oublié qu'en l'absence du mot-clé nonlocal, une variable cachée crée une portée locale :
def outer(): x = 0 def inner(): x += 1 # UnboundLocalError, x est considérée comme locale dans inner
Correct:
def outer(): x = 0 def inner(): nonlocal x x += 1
Histoire
Ils ont écrit une expression sur une ligne :
x = 5 y = (lambda: (x := x + 1))() # SyntaxError dans Python < 3.8, ou UnboundLocalError plus tard
Ils ont oublié la différence de portée pour les expressions et les lambda. Toutes les constructions ne prennent pas en charge l'affectation à l'intérieur d'une lambda, selon la version de Python.