Iterar en un archivo no funciona la segunda vez [duplicado]
Tengo un problema al iterar en un archivo. Esto es lo que escribo en el intérprete y el resultado:
>>> f = open('baby1990.html', 'rU')
>>> for line in f.readlines():
... print(line)
...
# ... all the lines from the file appear here ...
Cuando intento repetir el mismo archivo abierto nuevamente, ¡no obtengo nada!
>>> for line in f.readlines():
... print(line)
...
>>>
No hay ninguna salida. Para resolver esto, tengo que abrir close()
el archivo y luego abrirlo nuevamente para leerlo. ¿Es ese un comportamiento normal?
Sí, ese es un comportamiento normal. Básicamente, la primera vez lees hasta el final del archivo (puedes imaginarlo como si estuvieras leyendo una cinta), por lo que no puedes leer más a menos que lo restablezcas, ya sea usando para reposicionarlo f.seek(0)
al inicio del archivo. archivo, o cerrarlo y luego abrirlo nuevamente, lo que comenzará desde el principio del archivo.
Si lo prefiere, puede utilizar la with
sintaxis que cerrará automáticamente el archivo.
p.ej,
with open('baby1990.html', 'rU') as f:
for line in f:
print line
Una vez que este bloque termina de ejecutarse, el archivo se cierra automáticamente, por lo que puede ejecutar este bloque repetidamente sin cerrar explícitamente el archivo y leerlo de esta manera nuevamente.
A medida que el objeto de archivo lee el archivo, utiliza un puntero para realizar un seguimiento de dónde se encuentra. Si lees parte del archivo y vuelves a él más tarde, continuará donde lo dejaste. Si lee el archivo completo y vuelve al mismo objeto de archivo, será como leer un archivo vacío porque el puntero está al final del archivo y no queda nada por leer. Puede utilizar file.tell()
para ver en qué parte del archivo está el puntero y file.seek
configurarlo. Por ejemplo:
>>> file = open('myfile.txt')
>>> file.tell()
0
>>> file.readline()
'one\n'
>>> file.tell()
4L
>>> file.readline()
'2\n'
>>> file.tell()
6L
>>> file.seek(4)
>>> file.readline()
'2\n'
Además, debes saber que file.readlines()
lee el archivo completo y lo almacena como una lista. Es útil saberlo porque puedes reemplazar:
for line in file.readlines():
#do stuff
file.seek(0)
for line in file.readlines():
#do more stuff
con:
lines = file.readlines()
for each_line in lines:
#do stuff
for each_line in lines:
#do more stuff
También puedes iterar sobre un archivo, una línea a la vez, sin mantener todo el archivo en la memoria (esto puede ser muy útil para archivos muy grandes) haciendo:
for line in file:
#do stuff