À quoi sert le mot clé nonlocal ?

Le mot-clé nonlocal permet de gérer la portée des variables dans les fonctions imbriquées. Il permet de modifier des variables qui ne sont ni dans la fonction locale actuelle ni dans l'espace global.

Portée des variables

Les variables Python existent dans des portées différentes, qu'on appelle aussi des scopes. Une variable peut être locale à une fonction ou global au module.
Le mot-clé nonlocal est utilisé dans les fonctions imbriquées. Il permet à une fonction interne de modifier une variable de la fonction parente, qui n'est pas globale.

def fonction_externe():
    compteur = 0

    def fonction_interne():
        # Sans 'nonlocal', Python crée une nouvelle variable locale 'compteur'
        compteur = 10
        print(f"Dans la fonction interne : {compteur}")

    fonction_interne()
    print(f"Dans la fonction externe : {compteur}")

fonction_externe()
# Affiche :
# Dans la fonction interne : 10
# Dans la fonction externe : 0

Dans cet exemple, la variable compteur de la fonction_externe n'a pas été modifiée, car Python considère compteur = 10 comme une nouvelle variable dans l'espace local de la fonction_interne.

Le mot-clé nonlocal indique que nous souhaitons modifier la variable de la fonction englobante la plus proche :

def fonction_externe():
    compteur = 0

    def fonction_interne():
        # On déclare que 'compteur' fait référence à la variable de la fonction externe
        nonlocal compteur
        compteur = 10
        print(f"Dans la fonction interne : {compteur}")

    fonction_interne()
    print(f"Dans la fonction externe : {compteur}")

fonction_externe()
# Affiche :
# Dans la fonction interne : 10
# Dans la fonction externe : 10
Un instant

C'est bien la variable compteur de la fonction_externe qui est modifiée.

nonlocal ne se limite pas à la fonction parente immédiate. Il remontera les fonctions imbriquées jusqu'à trouver la variable, sans aller jusqu'à l'espace global.

def niveau1():
    x = "niveau 1"

    def niveau2():
        y = "niveau 2"

        def niveau3():
            nonlocal x  # Accède à x de niveau1 (2 niveaux plus haut)
            x = "modifié depuis niveau3"

        niveau3()

    niveau2()
    print(f"x dans niveau1 : {x}")

niveau1()
# x dans niveau1 : modifié depuis niveau3
Un instant

À noter

Si nonlocal est utilisé dans une fonction imbriquée, en ciblant la variable de la fonction parente la plus proche, global peut être utilisé dans n'importe quelle fonction pour modifier une variable de l'espace global.

Quand utiliser nonlocal ?

nonlocal est utilisé pour la gestion d'état avec les closures.
Une closure est une fonction qui se souvient dans l'environnement dans lequel elle a été créée.

def creer_compteur():
    count = 0

    def incrementer():
        nonlocal count
        count += 1
        return count

    return incrementer

# Chaque compteur "se souvient" de sa propre valeur
compteur1 = creer_compteur()
compteur2 = creer_compteur()

print(compteur1())  # 1
print(compteur1())  # 2
print(compteur2())  # 1 (indépendant du premier)
Un instant

L'exemple montre bien que la fonction interne capture la variable de la fonction qui l'entoure.

Bravo, tu es prêt à passer à la suite

Rechercher sur le site

Formulaire de contact

Inscris-toi à Docstring

Pour commencer ton apprentissage.

Tu as déjà un compte ? Connecte-toi.