Gestionnaires de contexte
Fait partie de la section Object Oriented Programming du Journey Python de Coddy — leçon 41 sur 64.
Les gestionnaires de contexte vous permettent d'allouer et de libérer des ressources précisément quand cela est nécessaire. Ils garantissent un nettoyage approprié même si des erreurs surviennent.
Voici l'exemple le plus courant utilisant l'instruction with :
with open('example.txt', 'w') as file:
file.write('Hello, world!')
# Le fichier est automatiquement fermé iciLe fichier est automatiquement fermé après le bloc, même si une exception survient.
Créez votre propre gestionnaire de contexte en implémentant les méthodes __enter__ et __exit__ :
class MyContext:
def __enter__(self):
print("Entering the context")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print("Exiting the context")
return False # Ne pas supprimer les exceptionsUtilisez votre gestionnaire de contexte personnalisé :
with MyContext() as ctx:
print("Inside the context")Sortie :
Entering the context
Inside the context
Exiting the contextCréez un gestionnaire de contexte plus pratique pour les connexions aux bases de données :
class DatabaseConnection:
def __init__(self, db_name):
self.db_name = db_name
self.connection = None
def __enter__(self):
# Connexion à self.db_name
print(f"Connecting to {self.db_name}")
self.connection = f"Connection to {self.db_name}"
return self.connection
def __exit__(self, exc_type, exc_val, exc_tb):
# Fermeture de la connexion à self.db_name
print(f"Closing connection to {self.db_name}")
self.connection = None
with DatabaseConnection("users_db") as conn:
print(f"Using {conn}")
print("Performing database operations...")Gérer les exceptions dans les gestionnaires de contexte :
class SafeContext:
def __enter__(self):
print("Setting up resources")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print("Cleaning up resources")
if exc_type:
print(f"An exception occurred: {exc_val}")
return False # Ne pas supprimer l'exception
with SafeContext():
print("Working with resources")
# raise ValueError("Something went wrong") # Décommenter pour testerSortie :
Connecting to users_db
Using Connection to users_db
Performing database operations...
Closing connection to users_db
Setting up resources
Working with resources
Cleaning up resourcesLa méthode __exit__ reçoit trois paramètres :
exc_type: Type d'exception (ou None)exc_val: Valeur de l'exception (ou None)exc_tb: Traceback de l'exception (ou None)
Point clé : Les gestionnaires de contexte utilisent les méthodes __enter__ et __exit__ pour gérer les ressources. L'instruction with appelle automatiquement ces méthodes, garantissant une configuration et un nettoyage appropriés. Ceci est particulièrement utile pour les fichiers, les connexions aux bases de données et d'autres ressources qui nécessitent un nettoyage garanti.
Défi
FacileDans ce défi, vous allez implémenter une classe de gestionnaire de contexte qui mesure le temps écoulé entre l'entrée et la sortie d'un bloc de contexte.
timer.py- Contient l'implémentation de la classeTimer(c'est le fichier que vous allez éditer)driver.py- Contient des cas de test complets (ne pas modifier)
Implémentez le gestionnaire de contexte Timer dans timer.py en suivant les commentaires TODO. La classe doit :
- Enregistrer l'heure de début lors de l'entrée dans un contexte
- Enregistrer l'heure de fin lors de la sortie
- Calculer et afficher le temps écoulé
Aide-mémoire
Les gestionnaires de contexte allouent et libèrent les ressources précisément quand cela est nécessaire, garantissant un nettoyage approprié même si des erreurs surviennent.
Utilisez l'instruction with pour une gestion automatique des ressources :
with open('example.txt', 'w') as file:
file.write('Hello, world!')
# Le fichier est automatiquement fermé iciCréez des gestionnaires de contexte personnalisés en implémentant les méthodes __enter__ et __exit__ :
class MyContext:
def __enter__(self):
print("Entering the context")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print("Exiting the context")
return False # Ne pas supprimer les exceptions
with MyContext() as ctx:
print("Inside the context")La méthode __exit__ reçoit trois paramètres :
exc_type: Type d'exception (ou None)exc_val: Valeur de l'exception (ou None)exc_tb: Traceback de l'exception (ou None)
Gérer les exceptions dans les gestionnaires de contexte :
class SafeContext:
def __enter__(self):
print("Setting up resources")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print("Cleaning up resources")
if exc_type:
print(f"An exception occurred: {exc_val}")
return False # Ne pas supprimer l'exceptionEssayez vous-même
from timer import Timer
import time
# Gestionnaire de cas de test
test_case = input()
if test_case == "basic_test":
# Test de fonctionnalité de base
with Timer():
# Simuler un travail
time.sleep(2) # Cela fait attendre le programme pendant 2 secondes
elif test_case == "nested_contexts":
# Tester les gestionnaires de contexte imbriqués
with Timer():
time.sleep(1)
with Timer():
time.sleep(1)
elif test_case == "exception_handling":
# Tester la gestion des exceptions au sein du contexte
try:
with Timer():
time.sleep(1)
raise ValueError("Test exception")
except ValueError as e:
print(f"Caught exception: {e}")
elif test_case == "zero_sleep":
# Test avec un sommeil minimal
with Timer():
time.sleep(0.001)
elif test_case == "multiple_timers":
# Tester plusieurs minuteurs en séquence
with Timer():
time.sleep(1)
with Timer():
time.sleep(0.5)
with Timer():
time.sleep(2)
elif test_case == "as_decorator":
# Tester le minuteur dans le contexte d'une fonction
def timed_function():
with Timer():
time.sleep(2)
timed_function()
else:
# Test par défaut - fonctionnalité de base
with Timer():
# Simuler un travail
time.sleep(2) # Cela fait attendre le programme pendant 2 secondes
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Object Oriented Programming
1Les fondamentaux de la POO
Fichiers externesIntroduction à la POOClasses vs ObjetsLe paramètre selfMéthodesAttributsMéthode constructeur (__init__)Récapitulatif - Calculatrice simple4Héritage
Héritage de baseLa fonction super()Redéfinition de méthodeHéritage multipleOrdre de résolution des méthodesRécapitulatif - Hiérarchie des employés7Méthodes spéciales
Introduction aux méthodes magiquesSurcharge d'opérateursMéthodes magiques de conteneurRécapitulatif - Liste personnalisée10Patrons de conception, Partie 1
Introduction aux patrons de conceptionPatron SingletonPatron FactoryPatron ObserverPatron Strategy2Décorateurs
Introduction aux décorateursDécorateur de propriétéDécorateur de méthode statiqueDécorateur de méthode de classe5Polymorphisme
Retour sur la redéfinition de méthodeDuck TypingClasses et méthodes abstraitesConception d'interfacesRécapitulatif - Calculateur de formes8Concepts avancés de la POO
Composition vs HéritageMixinsMéthodes statiques et de classeDécorateurs de classeGestionnaires de contexte11Patrons de conception, Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Méthode TemplatePatron ÉtatPatron Composite3Propriétés de classe
Variables d'instance vs variables de classeDécorateurs de propriétéAttributs privésRécapitulatif - Gestionnaire de compte bancaire