En Python, si abre un archivo sin llamar close()
o cierra el archivo pero no lo usa try
, finally
o la " with
" instrucción, ¿es un problema? ¿O es suficiente como práctica de codificación confiar en la recolección de basura de Python para cerrar todos los archivos? Por ejemplo, si uno hace esto:
for line in open("filename"):
# ... do stuff ...
... ¿esto es un problema porque el archivo nunca se puede cerrar y podría producirse una excepción que impida su cierre? ¿O se cerrará definitivamente al final de la for
declaración porque el archivo queda fuera de alcance?
python
file
garbage-collection
usuario553702
fuente
fuente
for
bloque. Su recuento de referencia irá a cero, haciendo que se cierre automáticamente, pero solo las funciones, clases y módulos definen ámbitos en Python, no otras declaraciones compuestas.for
bloques y funciones / clases / módulos. Es mucho más simple que eso: los objetos no tienen ámbitos, solo los nombres. No hay ningún nombre que se refiera a este objeto, por lo que no hay nada aquí para permanecer dentro o fuera del alcance.for
bucle y mencionando que el archivo se cierra por una razón completamente diferente. No entra en qué ámbitos hay en Python, ya que no es relevante aquí.Respuestas:
En su ejemplo, no se garantiza que el archivo se cierre antes de que salga el intérprete. En las versiones actuales de CPython, el archivo se cerrará al final del ciclo for porque CPython usa el recuento de referencias como su mecanismo principal de recolección de basura, pero eso es un detalle de implementación, no una característica del lenguaje. No se garantiza que otras implementaciones de Python funcionen de esta manera. Por ejemplo, IronPython, PyPy y Jython no usan el recuento de referencias y, por lo tanto, no cerrarán el archivo al final del ciclo.
Es una mala práctica confiar en la implementación de recolección de basura de CPython porque hace que su código sea menos portátil. Es posible que no tenga pérdidas de recursos si usa CPython, pero si alguna vez cambia a una implementación de Python que no usa el conteo de referencias, deberá revisar todo su código y asegurarse de que todos sus archivos estén cerrados correctamente.
Para su ejemplo use:
fuente
with open() as f
cierra automáticamente el archivo una vez hecho?with
proporciona la declaración, pero, por supuesto, para que esta magia funcione, el objeto debe tener los métodos especiales__enter__
y__exit__
, en este último, el objeto debe hacerclose
y cualquier otra cosa de limpieza que deba hacerse en el final de lawith
declaración ...Algunas pitones cerrarán los archivos automáticamente cuando ya no estén referenciadas, mientras que otras no lo harán y depende de la O / S cerrar los archivos cuando salga el intérprete de Python.
Incluso para las pitones que cerrarán los archivos por usted, el tiempo no está garantizado: podría ser inmediatamente o podría ser segundos / minutos / horas / días más tarde.
Entonces, si bien es posible que no experimente problemas con el Python que está utilizando, definitivamente no es una buena práctica dejar sus archivos abiertos. De hecho, en cpython 3 ahora recibirá advertencias de que el sistema tuvo que cerrar los archivos por usted si no lo hizo.
Moraleja: Limpia después de ti. :)
fuente
Aunque es bastante seguro usar tal construcción en este caso particular, existen algunas advertencias para generalizar dicha práctica:
fuente
El archivo obtiene basura recolectada y, por lo tanto, cerrada. El GC determina cuándo se cierra, no tú. Obviamente, esta no es una práctica recomendada porque podría alcanzar el límite de manejo de archivo abierto si no cierra los archivos tan pronto como termine de usarlos. ¿Qué pasa si dentro de ese
for
ciclo tuyo, abres más archivos y los dejas?fuente
for
declaración; no tendrá que esperar a la próxima ejecución de recolección de basura.Hola, es muy importante cerrar el descriptor de tu archivo cuando vayas a usar su contenido en el mismo script de Python. Hoy mismo me doy cuenta después de tanto tiempo de depuración. La razón es que el contenido se editará / eliminará / guardará solo después de que cierre su descriptor de archivo y los cambios se vean afectados.
Supongamos que tiene una situación en la que escribe contenido en un nuevo archivo y luego, sin cerrar fd, está usando ese archivo (no fd) en otro comando de shell que lee su contenido. En esta situación, no obtendrá los contenidos para el comando de shell como se esperaba y si intenta depurar no puede encontrar el error fácilmente. También puede leer más en la entrada de mi blog http://magnificentzps.blogspot.in/2014/04/importance-of-closing-file-descriptor.html
fuente
Durante el proceso de E / S, los datos se almacenan en el búfer: esto significa que se guardan en una ubicación temporal antes de escribirse en el archivo.
Python no vacía el búfer, es decir, escribe datos en el archivo, hasta que esté seguro de que ha terminado de escribir. Una forma de hacerlo es cerrar el archivo.
Si escribe en un archivo sin cerrar, los datos no llegarán al archivo de destino.
fuente