Leer todo el archivo en Python


Si lee un archivo completo con content = open('Path/to/file', 'r').read() ¿el controlador de archivo se deja abierto hasta que se cierra el script? ¿Hay un método más conciso para leer un archivo completo?

Author: tMC, 2011-09-14

2 answers

La respuesta a esa pregunta depende en cierta medida de la implementación particular de python.

Para entender de qué se trata todo esto, preste especial atención al objeto file real. En su código, ese objeto se menciona solo una vez, en una expresión, y se vuelve inaccesible inmediatamente después de que regrese la llamada read().

Esto significa que el objeto file es basura. La única pregunta que queda es " ¿Cuándo recopilará el objeto de archivo el recolector de basura?".

En CPython, que utiliza un contador de referencia, este tipo de basura se nota inmediatamente, y por lo que se recogerá inmediatamente. Esto no es generalmente cierto de otras implementaciones de python.

Una mejor solución, para asegurarse de que el archivo está cerrado, es este patrón:

with open('Path/to/file', 'r') as content_file:
    content = content_file.read()

Que siempre cerrará el archivo inmediatamente después de que finalice el bloque; incluso si se produce una excepción.

Editar: Para poner un punto más fino en él:

Distinto de file.__exit__(), que se llama "automáticamente" en un with configuración del administrador de contexto, la única otra forma en que se llama automáticamente a file.close() (es decir, que no se llame explícitamente a sí mismo) es a través de file.__del__(). Esto nos lleva a la pregunta de cuándo __del__() es llamado?

Un programa escrito correctamente no puede asumir que los finalizadores se ejecutarán en ningún momento antes de la finalización del programa.

-- http://blogs.msdn.com/b/oldnewthing/archive/2010/08/09/10047586.aspx

En particular:

Los objetos nunca se destruyen explícitamente; sin embargo, cuando se vuelven inalcanzables, pueden ser recolectados en basura. A una implementación se le permite posponer la recolección de basura u omitirla por completo - es una cuestión de calidad de implementación cómo se implementa la recolección de basura, siempre y cuando no se recopilen objetos que aún sean accesibles.

[...]

CPython utiliza actualmente un esquema de conteo de referencia con (opcional) detección retardada de enlaces cíclicos basura, que recoge la mayoría de los objetos tan pronto como se vuelven inalcanzables, pero no se garantiza que recoge basura que contiene referencias circulares.

-- https://docs.python.org/3.5/reference/datamodel.html#objects-values-and-types

(Énfasis mío)

Pero como sugiere, otras implementaciones pueden tener otro comportamiento. Como ejemplo, PyPy tiene 6 diferentes implementaciones de recolección de basura!

 453
Author: SingleNegationElimination,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-05 21:15:32

Puede usar pathlib.

Para Python 3.5 y superior:

from pathlib import Path
contents = Path(file_path).read_text()

Para versiones inferiores de Python use pathlib2 :

$ pip install pathlib2

Entonces:

from pathlib2 import Path
contents = Path(file_path).read_text()

Este es el verdaderoread_text aplicación :

def read_text(self, encoding=None, errors=None):
    """
    Open the file in text mode, read it, and close the file.
    """
    with self.open(mode='r', encoding=encoding, errors=errors) as f:
        return f.read()
 45
Author: Eyal Levin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-15 21:46:52