Se sai cosa sono i gestori di contesto , non hai bisogno di altro per capire i metodi magici __enter__
e __exit__
. Vediamo un esempio molto semplice.
In questo esempio sto aprendo miofile.txt con l'aiuto di aperto funzione di. Il blocco try/finally garantisce che anche se si verifica un'eccezione imprevista myfile.txt verrà chiuso.
fp=open(r"C:\Users\SharpEl\Desktop\myfile.txt")
try:
for line in fp:
print(line)
finally:
fp.close()
Ora sto aprendo stesso file con con dichiarazione:
with open(r"C:\Users\SharpEl\Desktop\myfile.txt") as fp:
for line in fp:
print(line)
Se si guarda il codice, non ho chiuso il file & non c'è try/finally blocco . Perché con l'istruzione si chiude automaticamente myfile.txt. Puoi anche controllarlo chiamando l'attributo print(fp.closed)
- che restituisce True
.
Questo perché gli oggetti file (FP nel mio esempio) restituiti dalla aperto funzione ha due metodi built-in __enter__
e __exit__
. È anche noto come gestore del contesto. Il metodo __enter__
viene chiamato all'inizio di con il blocco e il metodo __exit__
viene chiamato alla fine. Nota: con l'istruzione funziona solo con oggetti che supportano il protocollo di mamangement del contesto, ad esempio i metodi __enter__
e __exit__
. Una classe che implementa entrambi i metodi è nota come classe di gestione del contesto.
Ora è possibile definire la propria classe gestore contesto.
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")
spero ora avete conoscenza di base di entrambi i metodi magici __enter__
e __exit__
.
fonte
2016-07-31 15:29:36
Una buona spiegazione qui: http://effbot.org/ zone/python-with-statement.htm – Manur
@StevenVascellaro La modifica del codice di una domanda è generalmente una cattiva idea, ** specialmente ** quando ci sono errori nel codice. Questa domanda è stata posta con Py2 in mente, e non c'è motivo di aggiornarlo su Py3. – jpaugh