leer y cerrar un archivo en 1 línea de código


Ahora uso:

pageHeadSectionFile = open('pagehead.section.htm','r')
output = pageHeadSectionFile.read()
pageHeadSectionFile.close()

Pero para hacer que el código se vea mejor, puedo hacer:

output = open('pagehead.section.htm','r').read()

Al usar la sintaxis anterior, ¿cómo cierro el archivo para liberar recursos del sistema?

Author: Florian Pilz, 2011-11-04

11 answers

Realmente no tiene que cerrarlo - Python lo hará automáticamente durante la recolección de basura o al salir del programa. Pero como señaló @delnan, es mejor cerrarlo explícitamente por varias razones.

Entonces, lo que puedes hacer para mantenerlo corto, simple y explícito:

with open('pagehead.section.htm','r') as f:
    output = f.read()

Ahora son solo dos líneas y bastante legibles, creo.

 129
Author: Tim Pietzcker,
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-11-26 12:24:49

Python Standard Library Pathlib el módulo hace lo que buscas:

Path('pagehead.section.htm').read_text()

No olvides importar la ruta:

jsk@dev1:~$ python3
Python 3.5.2 (default, Sep 10 2016, 08:21:44)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from pathlib import Path
>>> (Path("/etc") / "hostname").read_text()
'dev1.example\n'

En Python 27 de instalar puestos pathlib o pathlib2

 19
Author: Janusz Skonieczny,
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
2018-01-12 17:34:02

Usando CPython, su archivo se cerrará inmediatamente después de que se ejecute la línea, porque el objeto de archivo se recolecta inmediatamente como basura. Sin embargo, hay dos inconvenientes:

  1. En implementaciones de Python diferentes de CPython, el archivo a menudo no se cierra inmediatamente, sino más bien en un momento posterior, más allá de su control.

  2. En Python 3.2 o superior, esto lanzará un ResourceWarning, si está habilitado.

Mejor invertir uno adicional línea:

with open('pagehead.section.htm','r') as f:
    output = f.read()

Esto asegurará que el archivo se cierre correctamente en todas las circunstancias.

 18
Author: Sven Marnach,
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
2013-07-03 08:51:21

Lo que puedes hacer es usar la instrucción with:

>>> with open('pagehead.section.htm', 'r') as fin:
...     output = fin.read()

La instrucción with tendrá cuidado de llamar a la función __exit__ del objeto dado incluso si algo malo sucedió en su código; está cerca de la sintaxis try... finally. Para el objeto devuelto por open, __exit__ corresponde al cierre del archivo.

Esta instrucción se ha introducido con Python 2.6.

 9
Author: Joël,
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
2011-11-04 15:39:46

Use ilio : (inline io):

Solo una llamada a la función en lugar de file open(), read(), close().

from ilio import read

content = read('filename')
 6
Author: iman,
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-08-21 13:42:49

No es necesario importar ninguna librería especial para hacer esto.

Use la sintaxis normal y abrirá el archivo para leer y luego lo cerrará.

with open("/etc/hostname","r") as f: print f.read() 

O

with open("/etc/hosts","r") as f: x = f.read().splitlines()

Lo que le da una matriz x que contiene las líneas, y se puede imprimir de la siguiente manera:

for i in range(len(x)): print x[i]

Estos one-liners son muy útiles para el mantenimiento - básicamente auto-documentación.

 4
Author: SDsolar,
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
2018-05-15 07:58:26
with open('pagehead.section.htm')as f:contents=f.read()
 2
Author: ,
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
2016-12-23 14:47:20

Con frecuencia hago algo como esto cuando necesito obtener algunas líneas que rodean algo que he greped en un archivo de registro:

$ grep -n "xlrd" requirements.txt | awk -F ":" '{print $1}'
54

$ python -c "with open('requirements.txt') as file: print ''.join(file.readlines()[52:55])"
wsgiref==0.1.2
xlrd==0.9.2
xlwt==0.7.5
 0
Author: Matthew Purdon,
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-06-17 09:12:39

Utilizando more_itertools.with_iter, es posible abrir, leer, cerrar y asignar un equivalente output en una línea (excluyendo la instrucción import):

import more_itertools as mit


output = "".join(line for line in mit.with_iter(open("pagehead.section.htm", "r")))

Aunque es posible, buscaría otro enfoque que no sea asignar el contenido de un archivo a una variable, es decir, iteración perezosa - esto se puede hacer usando un bloque tradicional with o en el ejemplo anterior eliminando join() e iterando output.

 0
Author: pylang,
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-08-29 01:30:27

Si quieres esa sensación cálida y borrosa solo ve con con.

Para python 3.6 ejecuté estos dos programas bajo un nuevo comienzo de IDLE, dando tiempos de ejecución de:

0.002000093460083008  Test A
0.0020003318786621094 Test B: with guaranteed close

Así que no hay mucha diferencia.

#--------*---------*---------*---------*---------*---------*---------*---------*
# Desc: Test A for reading a text file line-by-line into a list
#--------*---------*---------*---------*---------*---------*---------*---------*

import sys
import time

#                                  # MAINLINE
if __name__ == '__main__':
    print("OK, starting program...")

    inTextFile = '/Users/Mike/Desktop/garbage.txt'

#                                  # Test: A: no 'with;
    c=[]
    start_time = time.time()
    c = open(inTextFile).read().splitlines()
    print("--- %s seconds ---" % (time.time() - start_time))

    print("OK, program execution has ended.")
    sys.exit()                     # END MAINLINE

SALIDA:

OK, starting program...
--- 0.002000093460083008 seconds ---
OK, program execution has ended.

#--------*---------*---------*---------*---------*---------*---------*---------*
# Desc: Test B for reading a text file line-by-line into a list
#--------*---------*---------*---------*---------*---------*---------*---------*

import sys
import time

#                                  # MAINLINE
if __name__ == '__main__':
    print("OK, starting program...")

    inTextFile = '/Users/Mike/Desktop/garbage.txt'

#                                  # Test: B: using 'with'
    c=[]
    start_time = time.time()
    with open(inTextFile) as D: c = D.read().splitlines()
    print("--- %s seconds ---" % (time.time() - start_time))

    print("OK, program execution has ended.")
    sys.exit()                     # END MAINLINE

SALIDA:

OK, starting program...
--- 0.0020003318786621094 seconds ---
OK, program execution has ended.
 0
Author: CopyPasteIt,
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
2018-02-01 14:14:58

Curiosamente, nadie mencionó esto.

No me importa tener una función simple almacenada en algún lugar, que escriba solo una en la vida:

def readAndClose(fileName):
    f = open(filename,'r')
    val = f.read()
    f.close()
    return val

Entonces el resto es bastante fácil:

textFromFile = readAndClose(fileName)
 -1
Author: Daniel Möller,
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
2018-07-26 02:39:14