it-swarm.it

La chiusura esplicita dei file è importante?

In Python, se apri un file senza chiamare close() o chiudi il file ma non usi try-finally o l'istruzione "with" , è un problema? O è sufficiente come pratica di codifica fare affidamento sul Python garbage-collection per chiudere tutti i file? Ad esempio, se uno fa questo:

for line in open("filename"):
    # ... do stuff ...

... è un problema perché il file non può mai essere chiuso e potrebbe verificarsi un'eccezione che ne impedisce la chiusura? O sarà sicuramente chiuso alla conclusione dell'istruzione for perché il file non rientra nell'ambito?

136
user553702

Nel tuo esempio il file non è garantito per essere chiuso prima che l'interprete esca. Nelle attuali versioni di CPython il file verrà chiuso alla fine del ciclo for perché CPython utilizza il conteggio dei riferimenti come meccanismo principale di garbage collection ma è un dettaglio di implementazione, non una funzionalità del linguaggio. Altre implementazioni di Python non sono garantite per funzionare in questo modo. Ad esempio IronPython, PyPy e Jython non usano il conteggio dei riferimenti e quindi non chiuderanno il file alla fine del ciclo.

È una cattiva pratica fare affidamento sull'implementazione della garbage collection di CPython perché rende il codice meno portatile. Potresti non avere perdite di risorse se usi CPython, ma se passi mai a un'implementazione Python che non usa il conteggio dei riferimenti dovrai esaminare tutto il tuo codice e assicurarti che tutti i tuoi file siano chiusi correttamente .

Per il tuo esempio usa:

with open("filename") as f:
     for line in f:
        # ... do stuff ...
118
Peter Graham

Alcuni Python chiuderanno automaticamente i file quando non sono più referenziati, mentre altri non lo faranno ed è compito dell'O/S chiudere i file quando termina l'interprete Python.

Anche per i Python che chiuderanno i file per te, il tempismo non è garantito: potrebbe essere immediatamente o potrebbe essere secondi/minuti/ore/giorni dopo.

Quindi, anche se potresti non avere problemi con il Python che stai usando, non è sicuramente una buona pratica lasciare i tuoi file aperti. In effetti, in cpython 3 ora riceverai avvisi che il sistema ho dovuto chiudere i file per te se non l'hai fatto.

Morale: ripulisci dopo te stesso. :)

22
Ethan Furman

Sebbene sia abbastanza sicuro usare tale costrutto in questo caso particolare, ci sono alcuni avvertimenti per generalizzare tale pratica:

  • run può potenzialmente esaurire i descrittori di file, sebbene improbabile, immagina di cercare un bug del genere
  • potresti non essere in grado di eliminare detto file su alcuni sistemi, ad es. win32
  • se esegui qualcosa di diverso da CPython, non sai quando il file è chiuso per te
  • se si apre il file in modalità di scrittura o lettura-scrittura, non si sa quando i dati vengono scaricati
9
Dima Tisnek

Salve È molto importante chiudere il descrittore di file in una situazione quando si intende utilizzarne il contenuto nello stesso python. Oggi stesso mi rendo conto dopo così tanto tempo del debugging. La ragione è che il contenuto sarà essere modificato/rimosso/salvato solo dopo aver chiuso il descrittore di file e le modifiche sono interessate al file!

Supponiamo quindi di avere una situazione in cui scrivi il contenuto in un nuovo file e quindi senza chiudere fd stai usando quel file (non fd) in un altro comando Shell che legge il suo contenuto. In questa situazione non otterrai i contenuti per il comando Shell come previsto e se provi a eseguire il debug non riesci a trovare facilmente il bug. puoi anche leggere di più nel mio post di blog http://magnificentzps.blogspot.in/2014/04/importance-of-closing-file-descriptor.html

3
Zeel Shah

Il file ottiene la spazzatura raccolta e quindi chiusa. Il GC determina quando viene chiuso, non tu. Ovviamente, questa non è una pratica consigliata perché potresti toccare il limite di gestione dei file aperti se non chiudi i file non appena finisci di usarli. E se all'interno di quel tuo ciclo for, apri altri file e li lasci persistere?

3
Nam Nguyen

Durante il processo di I/O, i dati vengono bufferizzati: ciò significa che vengono conservati in una posizione temporanea prima di essere scritti nel file.

Python non scarica il buffer, ovvero scrive i dati nel file, fino a quando non si è sicuri di aver finito di scrivere. Un modo per farlo è chiudere il file.

Se si scrive su un file senza chiuderlo, i dati non verranno inseriti nel file di destinazione.

1
Sanket Nagrale