2009-02-22 7 views
14

avevo sempre pensato che un file sarebbe la fuga se è stato aperto senza essere chiuso, ma ho appena verificato che se entro le seguenti righe di codice, il file si chiude:Come Python chiude i file che sono stati gc?

>>> f = open('somefile.txt') 
>>> del f 

Solo per pura curiosità , come funziona? Ho notato che il file non include un metodo __ del __.

risposta

19

In CPython, almeno, i file vengono chiusi quando l'oggetto file viene deallocato. Vedere la funzione file_dealloc in Objects/fileobject.c nell'origine CPython. I metodi di Dealloc sono simili a __del__ per i tipi C, tranne alcuni dei problemi inerenti a __del__.

+1

Per chiarire, __del__ viene chiamato durante la garbage collection e nell'implementazione C di Python per gli oggetti file che si verifica nel momento in cui non vi sono più riferimenti all'oggetto file. –

4

Quindi il con la dichiarazione.

Per Python 2.5, utilizzare

from __future__ import with_statement 

(per Python 2.6 o 3.x, non fare nulla)

with open("someFile", "rU") as aFile: 
    # process the file 
    pass 
# At this point, the file was closed by the with statement. 
# Bonus, it's also out of scope of the with statement, 
# and eligible for GC. 
+0

Questo è quello che ho assunto anch'io. Ma su OS X in Python 2.5.1, le righe di codice che ho postato fanno in modo che l'interprete Python rilasci il file (verificato in Activity Monitor). –

+0

Python dovrebbe chiudere il file quando viene raccolto. Ho cercato di capire dove questo accade in fileobject.c, ma non è lì. Probabilmente è da qualche parte nel meccanismo gc, che è dove sto guardando in seguito. Mi piace questa domanda. –

+0

Sembra che mi sia perso in fileobject.c (vedi Gallagher). Vorrei davvero avere una migliore comprensione degli interni di CPython. –

0

ipotesi migliore è che, poiché il tipo di file è un tipo built-in, l'interprete stesso gestisce la chiusura del file sulla garbage collection.

In alternativa, si verifica solo dopo che l'interprete Python è uscito e tutti gli handle di file "persi" sono comunque chiusi.

+0

La mia comprensione del "tipo primitivo" (ricevuto da Java) non lascia il file come una primitiva, poiché non ci sono primitive in Python. –

+1

Penso che HUAGHAGUAH intendesse dire "tipo built-in". :) –

2

Python utilizza il conteggio dei riferimenti e la distruzione deterministica oltre alla garbage collection. Quando non ci sono più riferimenti a un oggetto, l'oggetto viene rilasciato immediatamente. Rilasciando un file lo si chiude.

Questo è diverso da ad es. Java dove c'è solo la garbage collection non deterministica. Ciò significa che connot sapere quando l'oggetto viene rilasciato, quindi dovrai chiudere il file manualmente.

Si noti che il conteggio dei riferimenti non è perfetto. Puoi avere oggetti con riferimenti circolari, che non sono raggiungibili dal programma. Ecco perché Python ha la garbage collection oltre al conteggio dei riferimenti.