with open(...) as f: è il modo standard di lavorare con i file tramite un gestore di contesto. Con questo approccio, Python garantisce la chiusura automatica del file all'uscita dal blocco with, anche se si verifica un'eccezione. Questo evita perdite di descrittori di file e blocchi del file.
All'interno del blocco puoi lavorare con il file usando i metodi dell'oggetto (f.read(), f.write(), ecc.). Dopo l'uscita dal blocco (anche in caso di errore), viene chiamato il metodo f.close().
Esempio:
with open('data.txt', 'w') as f: f.write('Hello!') # Qui il file è già chiuso
Domanda comune:
Possiamo essere certi che il file aperto tramite
opensi chiuderà subito dopo l'uscita dal bloccowith, anche se si verifica un'eccezione a metà blocco?
Risposta: Sì, questo è proprio quello che garantisce il contratto del gestore di contesto: indipendentemente dalle eccezioni, il metodo __exit__ viene chiamato all'uscita dal blocco, il che porta alla chiusura del file. Questo è il principale vantaggio rispetto alla chiamata esplicita di f.close().
Storia
In un grande progetto, le registrazioni nel log venivano effettuate tramite open('log.txt', 'a') e la chiamata esplicita f.write(), ma si dimenticava di f.close(). Dopo un lungo periodo di funzionamento, il processo ha esaurito tutti i descrittori di file del sistema operativo, il servizio ha smesso di funzionare.
Storia
Nel sistema di monitoraggio venivano aperti continuamente file tramite open, senza gestire le eccezioni. Quando si verificava un errore, il file rimaneva aperto, causando blocchi nel tentativo di riaprirlo da un altro processo.
Storia
Uno sviluppatore ha implementato la lettura di un grande file tramite open e ha immediatamente fatto un return a metà funzione, senza chiudere il file. Di conseguenza, diverse di queste operazioni hanno portato a un sovraccarico delle risorse di file, e il sistema operativo ha iniziato a bloccare nuove aperture.