Si vous savez ce que gestionnaires de contexte sont alors vous n'avez besoin de rien de plus pour comprendre __enter__
y __exit__
des méthodes magiques. Voyons un exemple très simple.
Dans cet exemple, j'ouvre le monfichier.txt avec l'aide de ouvrir fonction. Le site essayer/finalement Le bloc assure que même si une exception inattendue se produit monfichier.txt seront fermés.
fp=open(r"C:\Users\SharpEl\Desktop\myfile.txt")
try:
for line in fp:
print(line)
finally:
fp.close()
Maintenant, j'ouvre le même fichier avec avec déclaration :
with open(r"C:\Users\SharpEl\Desktop\myfile.txt") as fp:
for line in fp:
print(line)
Si vous regardez le code, je n'ai pas fermé le fichier et il n'y a pas de essayer/finalement bloc. Parce que avec la déclaration ferme automatiquement monfichier.txt . Vous pouvez même le vérifier en appelant print(fp.closed)
qui renvoie l'attribut True
.
Ceci est dû au fait que les objets fichiers (fp dans mon exemple) retournés par ouvrir a deux méthodes intégrées __enter__
y __exit__
. Il est également connu sous le nom de gestionnaire de contexte. __enter__
est appelée au début de avec et __exit__
est appelée à la fin.
Note : avec ne fonctionne qu'avec les objets qui prennent en charge le protocole de gestion de contexte (c'est-à-dire qu'ils ont __enter__
y __exit__
méthodes). Une classe qui met en œuvre les deux méthodes est connue comme classe de gestionnaire de contexte.
Maintenant, définissons notre propre gestionnaire de contexte classe.
class Log:
def __init__(self,filename):
self.filename=filename
self.fp=None
def logging(self,text):
self.fp.write(text+'\n')
def __enter__(self):
print("__enter__")
self.fp=open(self.filename,"a+")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print("__exit__")
self.fp.close()
with Log(r"C:\Users\SharpEl\Desktop\myfile.txt") as logfile:
print("Main")
logfile.logging("Test1")
logfile.logging("Test2")
J'espère que vous avez maintenant une compréhension de base des deux __enter__
y __exit__
des méthodes magiques.
20 votes
Une bonne explication ici : effbot.org/zone/python-with-statement.htm
7 votes
@StevenVascellaro Modifier le code d'une question est généralement une mauvaise idée, notamment lorsqu'il y a des erreurs dans le code. Cette question a été posée en pensant à Py2, et il n'y a aucune raison de la mettre à jour pour Py3.