2013-10-15 12 views
6

Se voglio utilizzare un oggetto file solo una volta, normalmente sarei ancora utilizzare il blocco with o esplicitamente chiudere l'oggetto file quando ho finito, perché la chiusura di un file sembra essere il giusto-cosa-to-do :Dopo aver passato la chiamata aperta come argomento a un'altra funzione, l'oggetto file è chiuso?

with open('filename','r') as f: 
    x = dosomething(f) 

o

f = open('filename','r') 
x = dosomething(f) 
f.close() 

Tuttavia, ho visto la gente usa passare la chiamata a open direttamente a una funzione senza salvare l'output a qualsiasi variabile, rendendo impossibile per chiudere esplicito LY:

x = dosomething(open('filename','r')) 

Quindi, è uno di questi vera,

  1. In qualche modo l'oggetto file senza nome viene chiuso
  2. Non importa, va bene a non chiudere il file

o è una cattiva pratica?

Inoltre, la risposta cambia se consento al file di essere letto/scritto?

Per essere chiari, dosomething potrebbe essere qualcosa di simile a np.array() o for i in f.readlines()

risposta

9

E 'una pratica povero. Non ha nulla a che fare con la modalità aperta (leggi, scrivi, leggi + scrivi, aggiungi, modalità binaria, modalità testo ...).

In CPython, "funziona quasi sempre" perché gli oggetti di file vengono chiusi automaticamente quando diventano rifiuti (irraggiungibile), e il riferimento di CPython contando solito raccoglie (non ciclico) di immondizia molto presto dopo che diventa spazzatura.

Ma fare affidamento su questo è davvero una cattiva pratica.

Se, ad esempio, dosomething(f) viene eseguito per un'ora prima che ritorni, è probabile che l'oggetto file rimanga aperto per tutto il tempo.

Nota: in alcuni casi, è possibile codificare dosomething(f) per chiudere esplicitamente l'oggetto del file passato. In questi casi, non è pratica poveri ;-)

tardi: una cosa correlata ho spesso visto è questo:

data = open(file_path).read() 

Nel CPython, l'oggetto file senza nome è garbage collection (e quindi anche chiuso) immediatamente dopo il completamento dell'istruzione, grazie al conteggio dei riferimenti di CPython. Le persone sono poi sorprese quando spostano il loro codice su una diversa implementazione Python, e ottengono "troppi file aperti!" denunce, contestazioni.Eh - serve 'em destra ;-)

Esempio:

open("Output.txt", "w").write("Welcome") 
print open("Output.txt").read() 

Questo stampa

Welcome 

in CPython, perché l'oggetto di file senza nome dalla prima affermazione è garbage collection (e chiuso) immediatamente quando termina la prima dichiarazione.

Ma:

output = open("Output.txt", "w") 
output.write("Welcome") 
print open("Output.txt").read() 

stamperà probabilmente una riga vuota CPython. In questo caso, l'oggetto file è associato a un nome (output), quindi è non garbage collector quando viene completata la seconda istruzione (un'implementazione più intelligente potrebbe teoricamente rilevare che output non viene mai più utilizzato, e garbage-collect subito, ma CPython no).

"Welcome" è probabilmente ancora nel buffer di memoria del file, quindi non è stato ancora scritto sul disco. Quindi la terza affermazione probabilmente trova un file vuoto e non stampa nulla.

In altre implementazioni di Python, entrambi gli esempi possono stampare linee vuote.

+2

Ottima risposta. Ho incluso un esempio. Si prega di controllare quello – thefourtheye

+1

Grazie! Risulta che ci sono molte sottigliezze, quindi ho aggiunto molte spiegazioni ;-) –

Problemi correlati