Fermetures et variables libres
Capturer un état dans des fonctions internes
Fermetures et variables libres est une leçon Python Academy gratuite sur CoddyKit. Ceci est la leçon 2 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.
Fonctions imbriquées
Python vous permet de définir une fonction à l'intérieur d'une autre fonction. La fonction interne est recréée à chaque exécution de la fonction externe.
def outer():
def inner():
return 'from inner'
return inner()
print(outer())La fonction interne voit les variables externes
Une fonction interne peut lire les variables définies dans la fonction englobante. On les appelle des variables libres, car elles ne sont pas locales à la fonction interne.
def outer():
message = 'hello'
def inner():
return message
return inner()
print(outer())Qu'est-ce qu'une fermeture ?
Une fermeture se produit lorsqu'une fonction interne est renvoyée et conserve la mémoire des variables libres de sa portée englobante, même après la fin de cette portée.
def make_greeter(name):
def greet():
return 'Hi ' + name
return greet
g = make_greeter('Ada')
print(g())L'état capturé persiste
La fonction externe a déjà renvoyé son résultat, mais la fermeture conserve toujours name. La valeur subsiste à l'intérieur de la fonction renvoyée.
def make_greeter(name):
def greet():
return 'Hi ' + name
return greet
a = make_greeter('Ada')
b = make_greeter('Bob')
print(a())
print(b())Une fabrique de multiplicateurs
Les fermetures sont particulièrement utiles comme fabriques produisant des fonctions personnalisées. Ici, chaque fonction renvoyée multiplie par un facteur capturé.
def multiplier(factor):
def multiply(n):
return n * factor
return multiply
double = multiplier(2)
triple = multiplier(3)
print(double(10))
print(triple(10))Chaque fermeture est indépendante
Chaque appel de la fabrique crée une fermeture distincte avec sa propre valeur capturée. Elles n'interfèrent pas entre elles.
def adder(amount):
def add(n):
return n + amount
return add
add5 = adder(5)
add100 = adder(100)
print(add5(1), add100(1))Examiner les valeurs capturées
Les noms capturés sont listés dans __code__.co_freevars, et leurs valeurs résident dans les cellules de __closure__.
def make(x):
def f():
return x
return f
fn = make(42)
print(fn.__code__.co_freevars)
print(fn.__closure__[0].cell_contents)Les fermetures capturent des variables, pas des valeurs
Une fermeture capture la variable elle-même et voit donc sa valeur finale. Cela est important lorsque la variable change après la création de la fermeture.
def build():
x = 1
def show():
return x
x = 99
return show
print(build()())Le piège de la liaison tardive dans une boucle
Un piège classique : les fermetures créées dans une boucle partagent toutes la même variable de boucle et capturent donc sa dernière valeur.
funcs = []
for i in range(3):
funcs.append(lambda: i)
print([f() for f in funcs])Corriger la liaison tardive
Liez la valeur courante à l'aide d'un argument par défaut afin que chaque fermeture capture sa propre copie au moment de la définition.
funcs = []
for i in range(3):
funcs.append(lambda i=i: i)
print([f() for f in funcs])Les fermetures comme objets légers
Une fermeture associe des données à un comportement, un peu comme un petit objet : elle est souvent plus claire qu'une classe complète dans les cas simples.
def counter_start(start):
def value():
return start
return value
c = counter_start(10)
print(c())Vérification rapide
Qu'est-ce qu'une fermeture en Python ?
Récapitulatif : fermetures et variables libres
Idées essentielles :
- Les fonctions internes peuvent lire les variables de la portée englobante (variables libres).
- Une fermeture est une fonction interne renvoyée qui conserve ces variables en mémoire.
- Chaque appel de fabrique crée une fermeture indépendante.
- Les fermetures capturent des variables, pas des valeurs, ce qui provoque le piège de la liaison tardive dans les boucles : corrigez-le avec un argument par défaut.
def power_of(exp):
return lambda base: base ** exp
square = power_of(2)
print(square(9))Questions Fréquemment Posées
La leçon « Fermetures et variables libres » est-elle gratuite ?
Oui — le texte complet de « Fermetures et variables libres » 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 « Fermetures et variables libres » ?
Capturer un état dans des fonctions internes 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 2 sur 4.
Combien de temps prend la leçon « Fermetures et variables libres » ?
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
- Fonctions de première classe
- Fermetures et variables libres
- nonlocal et état mutable
- Fonctions partielles