¿Por qué no puedo llamar a read () dos veces en un archivo abierto?

Para un ejercicio que estoy haciendo, estoy tratando de leer el contenido de un archivo dado dos veces usando el método read() . Extrañamente, cuando lo llamo por segunda vez, ¿no parece devolver el contenido del archivo como una cadena?

Aquí está el código

 f = f.open() # get the year match = re.search(r'Popularity in (\d+)', f.read()) if match: print match.group(1) # get all the names matches = re.findall(r'(\d+)(\w+)(\w+)', f.read()) if matches: # matches is always None 

Por supuesto, sé que esta no es la manera más eficiente o mejor, este no es el punto aquí. El punto es, ¿por qué no puedo llamar a read() dos veces? ¿Tengo que restablecer el manejador de archivos? ¿O cerrar / volver a abrir el archivo para hacer eso?

Calling read() lee todo el archivo y deja el cursor de lectura al final del archivo (sin nada más que leer). Si desea leer un cierto número de líneas a la vez, puede usar readline() , readlines() o iterar las líneas con la for line in handle:

Para responder a su pregunta directamente, una vez que se haya leído un archivo, con read() puede usar seek(0) para devolver el cursor de lectura al inicio del archivo (los documentos están aquí ). Si sabe que el archivo no va a ser demasiado grande, también puede guardar el resultado de read() en una variable, usándolo en sus expresiones de Findall.

PD. No olvide cerrar el archivo una vez que haya terminado con él;)

Sí, como arriba …

Sólo escribiré un ejemplo:

 >>> a = open('file.txt') >>> a.read() #output >>> a.seek(0) >>> a.read() #same output 

Todos los que han respondido esta pregunta hasta el momento tienen toda la razón: read() mueve a través del archivo, por lo que, después de haberlo llamado, no puede volver a llamarlo.

Lo que agregaré es que, en su caso particular, no necesita volver al inicio o volver a abrir el archivo, solo puede almacenar el texto que ha leído en una variable local y usarlo dos veces, o tantas veces como quieras, en tu progtwig:

 f = f.open() text = f.read() # read the file into a local variable # get the year match = re.search(r'Popularity in (\d+)', text) if match: print match.group(1) # get all the names matches = re.findall(r'(\d+)(\w+)(\w+)', text) if matches: # matches will now not always be None 

El puntero de lectura se mueve hacia después del último byte / carácter leído. Utilice el método seek() para rebobinar el puntero de lectura al principio.

Cada archivo abierto tiene una posición asociada.
Cuando lees () lees desde esa posición. Por ejemplo, read(10) lee los primeros 10 bytes de un archivo recién abierto, luego otra read(10) lee los siguientes 10 bytes. read() sin argumentos lee todos los contenidos del archivo, dejando la posición del archivo al final del archivo. La próxima vez que llame a read() no hay nada que leer.

Puede utilizar seek para mover la posición del archivo. O probablemente mejor en su caso sería hacer una read() y mantener el resultado para ambas búsquedas.

read() consume . Por lo tanto, puede restablecer el archivo o buscar el inicio antes de volver a leer. O, si se ajusta a su tarea, puede usar read(n) para consumir solo n bytes.

Siempre encuentro el método de lectura como un paseo por un callejón oscuro. Baja un poco y se detiene, pero si no está contando sus pasos, no está seguro de a qué distancia está. Seek da la solución al reposicionar, la otra opción es Tell que devuelve la posición a lo largo del archivo. Puede ser la api del archivo Python que combine la lectura y la búsqueda en un read_from (posición, bytes) para simplificarlo. Hasta que eso suceda, debería leer esta página .