Python Academy · Leçon

nonlocal et état mutable

Modifier la portée englobante

Leçon 3 sur 413 étapes

nonlocal et état mutable est une leçon Python Academy gratuite sur CoddyKit. Ceci est la leçon 3 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Python Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Python Academy comprend 4 leçons au total.

Lire et écrire des variables englobantes

Une fonction interne peut librement lire une variable englobante, mais si elle tente d'affecter une valeur à ce nom, Python le traite comme une nouvelle variable locale. Cela surprend souvent les débutants.

def outer():
    count = 0
    def inner():
        return count
    return inner()
print(outer())

Le piège de l'affectation

Affecter une valeur à un nom englobant sans déclarer cette intention le rend local, de sorte que la variable externe n'est jamais mise à jour. Ici, la modification est perdue.

def outer():
    count = 0
    def bump():
        count = count + 1
    try:
        bump()
    except UnboundLocalError as e:
        print('Error:', e)
outer()

Le mot-clé nonlocal

nonlocal indique qu'un nom désigne une variable de la fonction englobante la plus proche, afin que les affectations mettent à jour cette variable externe au lieu d'en créer une nouvelle locale.

def outer():
    count = 0
    def bump():
        nonlocal count
        count += 1
    bump()
    bump()
    return count
print(outer())

Une fermeture compteur

Avec nonlocal, vous pouvez créer un compteur qui conserve son état. Chaque appel modifie la variable capturée et mémorise sa progression.

def make_counter():
    count = 0
    def increment():
        nonlocal count
        count += 1
        return count
    return increment
c = make_counter()
print(c())
print(c())
print(c())

Des compteurs indépendants

Chaque compteur conserve son propre état, car chaque fermeture capture une variable distincte.

def make_counter():
    count = 0
    def inc():
        nonlocal count
        count += 1
        return count
    return inc
a = make_counter()
b = make_counter()
print(a(), a(), b())

Portée non locale et portée globale

nonlocal cible la portée d'une fonction englobante, tandis que global cible le niveau du module. Utilisez nonlocal pour les fermetures et global pour l'état partagé à l'échelle du module.

total = 0
def add_global(n):
    global total
    total += n
add_global(5)
add_global(3)
print(total)

Un état mutable sans nonlocal

Si la valeur englobante est un objet mutable comme une liste ou un dictionnaire, vous pouvez la modifier sur place sans nonlocal, car vous ne réaffectez pas le nom.

def make_logger():
    history = []
    def log(msg):
        history.append(msg)
        return history
    return log
log = make_logger()
log('start')
print(log('stop'))

Un accumulateur

Associer nonlocal à une fermeture permet de créer un accumulateur qui ajoute chaque valeur à un total mémorisé.

def make_accumulator():
    total = 0
    def add(n):
        nonlocal total
        total += n
        return total
    return add
acc = make_accumulator()
print(acc(10))
print(acc(5))
print(acc(100))

Un basculement simple

Le mot-clé de portée non locale permet d'inverser facilement un état booléen entre deux appels.

def make_toggle():
    on = False
    def toggle():
        nonlocal on
        on = not on
        return on
    return toggle
t = make_toggle()
print(t(), t(), t())

Réinitialiser l'état

Vous pouvez exposer plusieurs fonctions internes qui partagent le même état englobant, par exemple une pour ajouter et une autre pour réinitialiser.

def make_bank():
    balance = 0
    def deposit(n):
        nonlocal balance
        balance += n
        return balance
    def reset():
        nonlocal balance
        balance = 0
        return balance
    return deposit, reset
deposit, reset = make_bank()
print(deposit(50))
print(reset())

nonlocal nécessite une variable existante

nonlocal exige que le nom existe déjà dans une portée englobante ; sinon, Python lève une SyntaxError au moment de la définition. Il ne peut pas créer une nouvelle variable externe.

def outer():
    value = 'set'
    def inner():
        nonlocal value
        value = 'changed'
    inner()
    return value
print(outer())

Vérification rapide

À l'intérieur d'une fonction imbriquée, vous souhaitez réaffecter une variable de la fonction englobante. Quel mot-clé utilisez-vous ?

Récapitulatif : nonlocal et état mutable

Résumé :

  • Affecter une valeur à un nom englobant crée normalement une nouvelle variable locale ; nonlocal l'empêche.
  • nonlocal cible la portée de la fonction englobante ; global cible le module.
  • Modifier un objet mutable sur place ne nécessite aucune déclaration.
  • Les fermetures avec nonlocal permettent de créer des compteurs, des accumulateurs et des basculements qui mémorisent leur état.
def make_counter():
    n = 0
    def inc():
        nonlocal n
        n += 1
        return n
    return inc
c = make_counter()
print(c(), c())
Gratuit pour commencer

Apprends Python avec un tuteur IA — gratuit

Écris et exécute du vrai code dans ton navigateur, obtiens de l'aide instantanée d'un tuteur IA disponible 24h/24, et reprends là où tu t'es arrêté sur le web ou dans l'app.

Cours
76
Leçons
320

Questions Fréquemment Posées

La leçon « nonlocal et état mutable » est-elle gratuite ?

Oui — le texte complet de « nonlocal et état mutable » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Python Academy, passe à CoddyKit PRO. Le cours Python Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « nonlocal et état mutable » ?

Modifier la portée englobante Tu pratiques Python Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Python Academy ?

Aucune expérience préalable n'est requise. Python Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 3 sur 4.

Combien de temps prend la leçon « nonlocal et état mutable » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Python Academy ?

Oui. Chaque leçon Python Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Fonctions de première classe
  2. Fermetures et variables libres
  3. nonlocal et état mutable
  4. Fonctions partielles
← Retour à Python Academy