Gestionnaires de contexte Python : création personnalisée avec des blocs

Apprenez à écrire des gestionnaires de contexte personnalisés en Python. Maîtrisez le décorateur contextmanager et les méthodes __enter__/__exit__ pour la sécurité des ressources.

Essayez dans l'éditeur

Aperçu

Les gestionnaires de contexte sont un mécanisme élégant en Python conçu pour gérer la configuration et le démontage des ressources externes. Dans les logiciels, de nombreuses opérations nécessitent des paires d'actions : ouvrir et fermer des fichiers, se connecter et se déconnecter des bases de données, ou acquérir et libérer des verrous. Si un programme plante après l'étape d'installation mais avant l'étape de démontage, ces ressources restent verrouillées en mémoire. Les gestionnaires de contexte garantissent que les ressources sont nettoyées en toute sécurité en toutes circonstances.

La manière standard d'invoquer un gestionnaire de contexte consiste à utiliser l'instruction « with ». Sous le capot, tout objet utilisé dans une instruction « with » doit implémenter le protocole Context Manager. Ce protocole se compose de deux méthodes spéciales : `__enter__()` et `__exit__()`. Lorsque le bloc `with` commence, `__enter__()` est appelé pour préparer la ressource. Lorsque le bloc `with` termine ou déclenche une exception, `__exit__()` est automatiquement déclenché, recevant des informations sur toute exception levée afin qu'il puisse gérer le nettoyage ou supprimer les erreurs.

Pour des cas d'utilisation simples, écrire une classe avec les méthodes `__enter__` et `__exit__` peut sembler verbeux. Pour simplifier cela, la bibliothèque standard de Python fournit le module `contextlib`, qui comporte le décorateur `@contextmanager`. Ce décorateur vous permet d'écrire une fonction génératrice simple contenant une seule instruction « rendement ». Le code avant le « rendement » agit comme la configuration, la valeur générée agit comme la ressource et le code après le « rendement » représente le nettoyage. La maîtrise des gestionnaires de contexte garantit que vos applications restent sans fuite.

Sortie de code et d'exécution

Une classe personnalisée implémentant __enter__ et __exit__ pour gérer les limites de journalisation des exécutions.

context_managers.py
Essayez dans l'éditeur
class CustomManager:
    def __enter__(self):
        print("--> Resource Setup: Entering the block")
        return "RESOURCE_KEY"

    def __exit__(self, exc_type, exc_value, traceback):
        print("<-- Resource Teardown: Exiting the block")
        if exc_type:
            print(f"Exception Intercepted: {exc_value}")
        return True  # Suppress exceptions

with CustomManager() as res:
    print(f"Working inside block with resource: {res}")
    # Force an error to verify exception handling
    x = 1 / 0
print("Program continues running safely.")
Sortie terminale
--> Resource Setup: Entering the block
Working inside block with resource: RESOURCE_KEY
<-- Resource Teardown: Exiting the block
Exception Intercepted: division by zero
Program continues running safely.

Mise en œuvre étape par étape

  • Gestion des transactions de base de données (validation en cas de succès, restauration en cas d'erreur)
  • Acquérir et libérer des verrous de thread dans un code multithread
  • Redirection de la sortie standard (stdout) pendant les scripts de tests unitaires

Foire aux questions

Comment supprimer les exceptions dans un gestionnaire de contexte personnalisé ?

En renvoyant True depuis la méthode __exit__. S'il renvoie True, toute exception levée à l'intérieur du bloc sera supprimée.

Pouvez-vous combiner plusieurs gestionnaires de contexte dans une seule instruction ?

Oui, vous pouvez les séparer par des virgules, par exemple avec open('file1.txt') comme f1, open('file2.txt') comme f2:.

Sujets connexes

Ressources Python recommandées

Développez vos connaissances avec des didacticiels interactifs, des aide-mémoire et des comparaisons de codes associés.