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?
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.
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'
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:
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.
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.
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.
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')
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.
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()
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
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
.
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.
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)
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