2009-02-22 23 views
14

siempre había asumido que un archivo se filtraría si se abriese sin ser cerrado, pero yo sólo comprobado que si entro en las siguientes líneas de código, el archivo se cerrará:¿Cómo cierra python los archivos que se han gc'ed?

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

Sólo por curiosidad , ¿como funciona esto? Noto que el archivo no incluye un método __ del __.

Respuesta

19

En CPython, al menos, los archivos se cierran cuando el objeto del archivo se desasigna. Consulte la función file_dealloc en Objects/fileobject.c en la fuente CPython. Los métodos Dealloc son tipo-__del__ para tipos C, excepto sin algunos de los problemas inherentes a __del__.

+1

Para aclarar, se llama __del__ durante la recolección de elementos no utilizados, y en la implementación C de Python para los objetos de archivo que se produce en el momento en que ya no hay más referencias al objeto de archivo. –

4

De ahí la con la declaración.

Para Python 2.5, utilice

from __future__ import with_statement 

(Para Python 2.6 o 3.x, no hacer nada)

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

Eso es lo que asumí también. Pero en OS X en Python 2.5.1, las líneas de código que publiqué hacen que el intérprete de Python libere el archivo (verificado en el Monitor de actividad). –

+0

Se supone que Python cierra el archivo cuando se recopila. He estado buscando dónde sucede esto en fileobject.c, pero no está allí. Probablemente esté en algún lugar del mecanismo de GC, que es donde estoy buscando a continuación. Me gusta esta pregunta –

+0

Parece que lo perdí en fileobject.c (ver Gallagher). Realmente me gustaría tener una mejor comprensión de las partes internas de CPython. –

0

mejor conjetura es que debido a que el tipo de archivo es un tipo incorporado, el intérprete maneja el cierre del archivo en la recolección de basura.

O bien, solo está revisando después de que el intérprete de python haya salido, y todos los identificadores de archivo "filtrados" estén cerrados de todos modos.

+0

Mi comprensión del "tipo primitivo" (recibido de Java) no deja el archivo como primitivo, ya que no hay primitivas en Python. –

+1

Creo que HUAGHAGUAH quería decir "tipo incorporado". :) –

2

Python utiliza el recuento de referencias y la destrucción determinística además de la recolección de basura. Cuando ya no hay más referencias a un objeto, el objeto se libera inmediatamente. Liberar un archivo lo cierra.

Esto es diferente a, p. Java donde solo hay recolección de basura no determinista. Esto significa que no sabe cuándo se libera el objeto, por lo que tendrá que cerrarlo manualmente.

Tenga en cuenta que el recuento de referencias no es perfecto. Puede tener objetos con referencias circulares, que no son accesibles desde el programa. Es por eso que Python tiene recolección de basura además del recuento de referencias.

Cuestiones relacionadas