Exercice 01 : Créateur de Compteur avec nonlocal
Objectif
Cet exercice a pour but de vous faire utiliser le mot-clé nonlocal pour créer une "closure" qui agit comme un compteur. Cela illustre comment une fonction interne peut modifier l'état de sa fonction parente.
Contexte
Une "closure" (fermeture) est une fonction qui se souvient de l'environnement dans lequel elle a été créée. En d'autres termes, elle a accès aux variables de la fonction qui l'a définie, même après que cette fonction parente a terminé son exécution.
En utilisant nonlocal, on peut créer des fonctions qui maintiennent un état interne, ce qui est une alternative légère à l'utilisation d'une classe pour des cas simples.
Énoncé
-
Créez un nouveau fichier Python nommé
counter_factory.py. -
Définissez une fonction "factory"
creer_compteur.- Cette fonction ne prend pas d'arguments.
- À l'intérieur de
creer_compteur, initialisez une variablecompteà0. C'est la variable de la portée englobante (Enclosing).
-
Définissez une fonction interne
incrementer.- Cette fonction doit être définie à l'intérieur de
creer_compteur. - Elle ne prend pas d'arguments.
- Utilisez le mot-clé
nonlocalpour déclarer que vous voulez modifier la variablecomptede la fonctioncreer_compteur. - Incrémentez
comptede 1. - La fonction
incrementerdoit retourner la nouvelle valeur decompte.
- Cette fonction doit être définie à l'intérieur de
-
La fonction
creer_compteurdoit retourner la fonctionincrementer. -
Testez votre créateur de compteurs.
- Dans le bloc principal (
if __name__ == '__main__':), créez un premier compteur en appelantcreer_compteur(). - Appelez ce premier compteur plusieurs fois et affichez le résultat pour vérifier qu'il s'incrémente correctement.
- Créez un deuxième compteur en appelant à nouveau
creer_compteur(). - Appelez ce deuxième compteur et vérifiez que son état est indépendant du premier.
- Dans le bloc principal (
Résultat Attendu
L'exécution de votre script de test doit montrer que chaque compteur maintient son propre état, indépendant des autres.
--- Compteur 1 ---
1
2
3
--- Compteur 2 ---
1
--- Compteur 1 (suite) ---
4
Cliquez ici pour voir un exemple de code de solution
# counter_factory.py
def creer_compteur():
"""
Une fonction factory qui crée et retourne une fonction compteur.
Chaque compteur a son propre état indépendant.
"""
# E - Portée Englobante (Enclosing Scope)
compte = 0
def incrementer():
"""
Fonction interne qui incrémente et retourne la variable 'compte'
de sa portée englobante.
"""
# L - Portée Locale (Local Scope)
# On déclare que 'compte' n'est pas une nouvelle variable locale,
# mais bien celle de la portée englobante.
nonlocal compte
compte += 1
return compte
# La factory retourne la fonction interne.
return incrementer
# --- Tests ---
if __name__ == "__main__":
# Crée une première instance de compteur.
compteur1 = creer_compteur()
print("--- Compteur 1 ---")
print(compteur1())
print(compteur1())
print(compteur1())
# Crée une deuxième instance. Elle aura son propre 'compte'.
compteur2 = creer_compteur()
print("\n--- Compteur 2 ---")
print(compteur2())
print("\n--- Compteur 1 (suite) ---")
# On vérifie que l'état de compteur1 n'a pas été affecté.
print(compteur1())