ProgrammationDéveloppeur Backend

Qu'est-ce que la portée (scope) des variables en Python et comment fonctionne le mot-clé `global` ? Donnez un exemple pratique où une mauvaise compréhension de la portée conduit à des erreurs.

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

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 :

  • Local (locale) — à l'intérieur d'une fonction.
  • Enclosing (englobante) — à l'intérieur de fonctions externes pour des fonctions imbriquées.
  • Global (globale) — au niveau du module.
  • Built-in (noms intégrés de Python).

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.

Question piège.

"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.

Exemples d'erreurs réelles dues à l'ignorance des subtilités du sujet.


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.