GeeksforGeeks
Gestion des ressources : Dans n’importe quel langage de programmation, l’utilisation de ressources telles que les opérations de fichiers ou les connexions à la base de données est très courante. Mais l’offre de ces ressources est limitée. Par conséquent, le principal problème réside dans le fait de s’assurer de libérer ces ressources après utilisation. S’ils ne sont pas relâchés, cela entraînera une fuite des ressources et pourrait entraîner un ralentissement ou une panne du système. Il serait très utile que l’utilisateur dispose d’un mécanisme pour la configuration automatique et le démontage des ressources.En Python, cela peut être réalisé par l’utilisation de gestionnaires de contexte qui facilitent la bonne gestion des ressources. La façon la plus courante d’effectuer des opérations de fichiers consiste à utiliser le mot clé with comme indiqué ci-dessous:
with
open
(
"test.txt"
) as f:
data
=
f.read()
Let’s take the example of file gestion. Lorsqu’un fichier est ouvert, un descripteur de fichier est consommé, ce qui est une ressource limitée. Seul un certain nombre de fichiers peuvent être ouverts par un processus à la fois. Le programme suivant le démontre.
file_descriptors
=
for
x
in
range
(
100000
):
file_descriptors.append(
open
(
'test.txt'
,
'w'
))
Sortie:
Traceback (most recent call last): File "context.py", line 3, in OSError: Too many open files: 'test.txt'
Un message d’erreur indiquant que trop de fichiers sont ouverts. L’exemple ci-dessus est un cas de fuite de descripteur de fichier. Cela arrive parce qu’il y a trop de fichiers ouverts et qu’ils ne sont pas fermés. Il peut y avoir des chances qu’un programmeur oublie de fermer un fichier ouvert.
Gestion des ressources à l’aide du gestionnaire de contexte :
Supposons qu’un bloc de code déclenche une exception ou s’il a un algorithme complexe avec plusieurs chemins de retour, il devient fastidieux de fermer un fichier à tous les endroits.
Généralement dans d’autres langues lorsque vous travaillez avec des fichiers, try-except-finally est utilisé pour s’assurer que la ressource de fichier est fermée après utilisation, même s’il existe une exception.Python fournit un moyen facile de gérer les ressources : les gestionnaires de contexte. Le mot clé with est utilisé. Lorsqu’il est évalué, il devrait en résulter un objet qui effectue une gestion de contexte. Les gestionnaires de contexte peuvent être écrits à l’aide de classes ou de fonctions (avec des décorateurs).
Création d’un gestionnaire de contexte :
Lors de la création de gestionnaires de contexte à l’aide de classes, l’utilisateur doit s’assurer que la classe possède les méthodes : __enter__() et __exit__(). Le __enter__() renvoie la ressource qui doit être gérée et le __exit__() ne renvoie rien mais effectue les opérations de nettoyage.
Tout d’abord, permet de créer une classe simple appelée ContextManager pour comprendre la structure de base de la création de gestionnaires de contexte à l’aide de classes, comme indiqué ci-dessous:
class
ContextManager():
def
__init__(
self
):
print
(
'init method called'
)
def
__enter__(
self
):
print
(
'enter method called'
)
return
self
def
__exit__(
self
, exc_type, exc_value, exc_traceback):
print
(
'exit method called'
)
with ContextManager() as manager:
print
(
'with statement block'
)
Output:
init method calledenter method calledwith statement blockexit method called
Dans ce cas, un objet ContextManager est créé. Ceci est affecté à la variable après le mot-clé as, c’est-à-dire manager. Lors de l’exécution du programme ci-dessus, les éléments suivants sont exécutés en séquence:
- __init__()
- __enter__()
- corps de l’instruction (code à l’intérieur du bloc with)
- __exit__()
Gestion des fichiers à l’aide du gestionnaire de contexte:
Appliquons le concept ci-dessus pour créer une classe qui aide à la gestion des ressources de fichiers.La classe FileManager aide à ouvrir un fichier, à écrire / lire le contenu, puis à le fermer.
class
FileManager():
def
__init__(
self
, filename, mode):
self
.filename
=
filename
self
.mode
=
mode
self
.
file
=
None
def
__enter__(
self
):
self
.
file
=
open
(
self
.filename,
self
.mode)
return
self
.
file
def
__exit__(
self
, exc_type, exc_value, exc_traceback):
self
.
file
.close()
with FileManager(
'test.txt'
,
'w'
) as f:
f.write(
'Test'
)
print
(f.closed)
Sortie:
True
Gestion des fichiers à l’aide du gestionnaire de contexte et de l’instruction with:
Lors de l’exécution du bloc with, les opérations suivantes se produisent en séquence:
- Un objet FileManager est créé avec test.txt comme nom de fichier et w(write) comme mode lorsque la méthode __init__ est exécutée.
- La méthode __enter__ ouvre le test.fichier txt en mode écriture (opération de configuration) et renvoie l’objet FileManager à la variable f.
- Le texte ‘Test’ est écrit dans le fichier.
- La méthode __exit__ se charge de fermer le fichier à la sortie du bloc with (opération de démontage).
Lorsque print(f.closed) est exécuté, la sortie est Vraie car le gestionnaire de fichiers a déjà pris soin de fermer le fichier, ce qui devait être fait explicitement.
Gestion de la connexion à la base de données à l’aide du gestionnaire de contexte :
Créons un système simple de gestion de la connexion à la base de données. Le nombre de connexions de base de données pouvant être ouvertes à la fois est également limité (tout comme les descripteurs de fichiers). Par conséquent, les gestionnaires de contexte sont utiles pour gérer les connexions à la base de données car il pourrait y avoir des chances que le programmeur oublie de fermer la connexion.
from
pymongo
import
MongoClient
class
MongoDBConnectionManager():
def
__init__(
self
, hostname, port):
self
.hostname
=
hostname
self
.port
=
port
self
.connection
=
None
def
__enter__(
self
):
self
.connection
=
MongoClient(
self
.hostname,
self
.port)
return
self
def
__exit__(
self
, exc_type, exc_value, exc_traceback):
self
.connection.close()
with MongoDBConnectionManager(
'localhost'
,
'27017'
) as mongo:
collection
=
mongo.connection.SampleDb.test
data
=
collection.find({
'_id'
:
1
})
Gestion de la connexion à la base de données à l’aide du gestionnaire de contexte et de l’instruction with :
Lors de l’exécution du bloc with, les opérations suivantes se produisent en séquence :
- Un objet MongoDBConnectionManager est créé avec localhost comme nom d’hôte et 27017 comme port lorsque la méthode __init__ est exécutée.
- La méthode __enter__ ouvre la connexion mongodb et renvoie l’objet MongoDBConnectionManager à la variable mongo.
- La collection de tests dans la base de données SampleDb est accessible et le document avec _id=1 est récupéré. Le champ nom du document est imprimé.
- La méthode __exit__ se charge de fermer la connexion à la sortie du bloc with (opération de démontage).