Iterar en un archivo no funciona la segunda vez [duplicado]

Resuelto MYZ asked hace 12 años • 4 respuestas

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?

MYZ avatar Apr 21 '12 08:04 MYZ
Aceptado

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 withsintaxis 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.

Levon avatar Apr 21 '2012 01:04 Levon

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.seekconfigurarlo. 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
Bi Rico avatar Apr 21 '2012 01:04 Bi Rico