L'instruction with en Python
Dans cet article, nous allons aborder l'instruction with
en Python, qui est essentielle pour gérer les ressources telles que les fichiers et les connexions réseau.
Nous verrons comment cette instruction fonctionne, les scénarios d'utilisation courants et des exemples détaillés pour vous aider à comprendre et à maîtriser cette fonctionnalité de Python.
Pourquoi utiliser l'instruction with
L'instruction with
simplifie la gestion des ressources en garantissant que les opérations d'initialisation et de finalisation sont effectuées de manière cohérente et fiable.
Par exemple, lors de l'ouverture d'un fichier, il est important de le fermer correctement après avoir terminé de l'utiliser.
Avec l'instruction with
, vous n'avez pas besoin de vous soucier de fermer le fichier manuellement :
with open('mon_fichier.txt', 'r') as fichier:
contenu = fichier.read()
Dans cet exemple, le fichier sera automatiquement fermé à la fin du bloc with
, même en cas d'exception.
Le protocole de gestion des contextes
L'instruction with
repose sur le protocole de gestion des contextes, qui est défini par deux méthodes spéciales : __enter__
et __exit__
.
Un objet implémentant ces deux méthodes est appelé un objet de contexte.
Lorsqu'un objet de contexte est utilisé dans une déclaration with, la méthode __enter__
est appelée au début du bloc, et la méthode __exit__
est appelée à la fin.
Prenons l'exemple d'un fichier :
with open('mon_fichier.txt', 'r') as fichier:
contenu = fichier.read()
Lorsque le bloc with
commence, la méthode open
est appelée, et retourne un objet fichier.
Cet objet implémente les méthodes __enter__
et __exit__
.
La méthode __enter__
est alors appelée, et le fichier est ouvert.
À la fin du bloc with
, la méthode __exit__
est appelée, et le fichier est fermé automatiquement.
Créer vos propres objets de contexte
La bonne nouvelle, c'est que vous pouvez créer vos propres objets de contexte en définissant les méthodes __enter__
et __exit__
dans votre classe.
Par exemple, voici comment créer un objet de contexte pour mesurer le temps d'exécution d'un bloc de code :
import time
class Chronometre:
def __enter__(self):
self.debut = time.time()
return self
def __exit__(self, exc_type, exc_value, traceback):
self.fin = time.time()
self.duree = self.fin - self.debut
print(f"Temps écoulé : {self.duree:.2f} secondes")
with Chronometre() as chrono:
# Bloc de code dont vous souhaitez mesurer le temps d'exécution
liste = [i**2 for i in range(100000)]
Dans cet exemple, la méthode __enter__
enregistre l'heure de début, et la méthode __exit__
enregistre l'heure de fin et affiche la durée.
Utiliser plusieurs objets de contexte
Il est possible d'utiliser plusieurs objets de contexte dans une seule déclaration with
. Par exemple, si vous souhaitez copier le contenu d'un fichier dans un autre, vous pouvez le faire comme suit :
with open('fichier_source.txt', 'r') as fichier_source, open('fichier_destination.txt', 'w') as fichier_destination:
for ligne in fichier_source:
fichier_destination.write(ligne)
Dans cet exemple, deux objets de contexte sont utilisés simultanément pour ouvrir le fichier source en mode lecture et le fichier destination en mode écriture. Le contenu est ensuite copié ligne par ligne.
Les décorateurs de contexte
Python permet également de créer des décorateurs de contexte en utilisant des fonctions génératrices (yield
)
Les décorateurs de contexte sont une alternative aux objets de contexte pour certaines situations.
Par exemple, voici un décorateur de contexte pour mesurer le temps d'exécution d'une fonction :
from contextlib import contextmanager
import time
@contextmanager
def chronometre():
debut = time.perf_counter()
yield
fin = time.perf_counter()
duree = fin - debut
print(f"Temps écoulé : {duree:.2f} secondes")
# Utilisation du décorateur de contexte chronometre
with chronometre():
# Bloc de code dont vous souhaitez mesurer le temps d'exécution
liste = [i**2 for i in range(100000)]
Dans cet exemple, la fonction chronometre
est définie comme un décorateur de contexte à l'aide du décorateur @contextmanager
et de la fonction génératrice yield
.