logo

avec instruction en Python

En Python, avec déclaration est utilisé dans la gestion des exceptions pour rendre le code plus propre et beaucoup plus lisible. Il simplifie la gestion des ressources communes telles que les flux de fichiers. Observez l'exemple de code suivant sur la façon dont l'utilisation de l'instruction with rend le code plus propre.

Python3




js en cours de chargement





# file handling> # 1) without using with statement> file> => open>(>'file_path'>,>'w'>)> file>.write(>'hello world !'>)> file>.close()> # 2) without using with statement> file> => open>(>'file_path'>,>'w'>)> try>:> >file>.write(>'hello world'>)> finally>:> >file>.close()>



>

>

Python3




# using with statement> with>open>(>'file_path'>,>'w'>) as>file>:> >file>.write(>'hello world !'>)>

>

>

Notez que contrairement aux deux premières implémentations, il n’est pas nécessaire d’appeler file.close() lors de l’utilisation de l’instruction with. L'instruction with elle-même garantit l'acquisition et la libération appropriées des ressources. Une exception lors de l'appel file.write() dans la première implémentation peut empêcher la fermeture correcte du fichier, ce qui peut introduire plusieurs bugs dans le code, c'est-à-dire que de nombreuses modifications apportées aux fichiers ne prennent effet que lorsque le fichier est correctement fermé. La deuxième approche de l'exemple ci-dessus prend en charge toutes les exceptions, mais l'utilisation de l'instruction with rend le code compact et beaucoup plus lisible. Ainsi, l'instruction with permet d'éviter les bogues et les fuites en garantissant qu'une ressource est correctement libérée lorsque le code utilisant la ressource est complètement exécuté. L'instruction with est couramment utilisée avec les flux de fichiers, comme indiqué ci-dessus, ainsi qu'avec les verrous, les sockets, les sous-processus et les telnets, etc.

Prise en charge de l'instruction with dans les objets définis par l'utilisateur

Il n'y a rien de spécial dans open() qui le rend utilisable avec l'instruction with et la même fonctionnalité peut être fournie dans les objets définis par l'utilisateur. La prise en charge de l'instruction with dans vos objets garantira que vous ne laisserez jamais aucune ressource ouverte. Pour utiliser l'instruction with dans des objets définis par l'utilisateur, il vous suffit d'ajouter les méthodes __enter__() et __exit__() dans les méthodes objet. Considérez l’exemple suivant pour plus de précisions.

Python3

surcharge de méthode




# a simple file writer object> class> MessageWriter(>object>):> >def> __init__(>self>, file_name):> >self>.file_name>=> file_name> > >def> __enter__(>self>):> >self>.>file> => open>(>self>.file_name,>'w'>)> >return> self>.>file> >def> __exit__(>self>,>*>args):> >self>.>file>.close()> # using with statement with MessageWriter> with MessageWriter(>'my_file.txt'>) as xfile:> >xfile.write(>'hello world'>)>

>

classe abstraite Java

>

Examinons le code ci-dessus. Si vous remarquez, ce qui suit le mot clé with est le constructeur de MessageWriter. Dès que l'exécution entre dans le contexte de l'instruction with, un objet MessageWriter est créé et python appelle ensuite la méthode __enter__(). Dans cette méthode __enter__(), initialisez la ressource que vous souhaitez utiliser dans l'objet. Cette méthode __enter__() doit toujours renvoyer un descripteur de la ressource acquise. Que sont les descripteurs de ressources ? Ce sont les handles fournis par le système d’exploitation pour accéder aux ressources demandées. Dans le bloc de code suivant, file est un descripteur de la ressource de flux de fichiers.

Python




file> => open>(>'hello.txt'>)>

>

>

Dans l'exemple MessageWriter fourni ci-dessus, la méthode __enter__() crée un descripteur de fichier et le renvoie. Le nom xfile est utilisé ici pour faire référence au descripteur de fichier renvoyé par la méthode __enter__(). Le bloc de code qui utilise la ressource acquise est placé à l'intérieur du bloc de l'instruction with. Dès que le code à l’intérieur du bloc with est exécuté, la méthode __exit__() est appelée. Toutes les ressources acquises sont libérées dans la méthode __exit__(). C'est ainsi que nous utilisons l'instruction with avec des objets définis par l'utilisateur. Cette interface des méthodes __enter__() et __exit__() qui fournit la prise en charge de l'instruction with dans les objets définis par l'utilisateur est appelée Gestionnaire de contexte .

Le module contextlib

Un gestionnaire de contexte basé sur les classes, comme indiqué ci-dessus, n'est pas le seul moyen de prendre en charge l'instruction with dans les objets définis par l'utilisateur. Le contextelib Le module fournit quelques abstractions supplémentaires basées sur l'interface de base du gestionnaire de contexte. Voici comment nous pouvons réécrire le gestionnaire de contexte pour l'objet MessageWriter à l'aide du module contextlib.

Python3


classe abstraite vs interface



from> contextlib>import> contextmanager> class> MessageWriter(>object>):> >def> __init__(>self>, filename):> >self>.file_name>=> filename> >@contextmanager> >def> open_file(>self>):> >try>:> >file> => open>(>self>.file_name,>'w'>)> >yield> file> >finally>:> >file>.close()> # usage> message_writer>=> MessageWriter(>'hello.txt'>)> with message_writer.open_file() as my_file:> >my_file.write(>'hello world'>)>

>

>

Dans cet exemple de code, en raison de rendement instruction dans sa définition, la fonction open_file() est une fonction générateur . Lorsque cette fonction open_file() est appelée, elle crée un descripteur de ressource nommé file. Ce descripteur de ressource est ensuite transmis à l'appelant et est représenté ici par la variable my_file. Une fois le code à l’intérieur du bloc with exécuté, le contrôle du programme revient à la fonction open_file(). La fonction open_file() reprend son exécution et exécute le code suivant l'instruction rendement. Cette partie de code qui apparaît après l'instruction rendement libère les ressources acquises. Le @contextmanager voici un décorateur . L'implémentation précédente basée sur les classes et cette implémentation basée sur un générateur de gestionnaires de contexte sont les mêmes en interne. Si ce dernier semble plus lisible, il nécessite la connaissance des générateurs, des décorateurs et du rendement.