Lectura de archivos con Python

Para trabajar con datos almacenados, el manejo de archivos pertenece al conocimiento básico de todo programador profesional de Python. Desde su primer lanzamiento, tanto la lectura como...

Para trabajar con datos almacenados, el manejo de archivos pertenece al conocimiento básico de todo programador profesional de Python. Desde su primera versión, tanto la lectura como la escritura de datos en archivos son funciones integradas de Python. En comparación con otros lenguajes de programación como C o Java, es bastante simple y solo requiere unas pocas líneas de código. Además, no es necesario cargar ningún módulo adicional para hacerlo correctamente.

Conceptos básicos de los archivos en Python

Los métodos comunes para operar con archivos son open() para abrir un archivo, seek() para establecer la posición actual del archivo en el desplazamiento dado, y close() para cerrar el objeto de archivo cuando Ya terminé de usarlo. El método open() devuelve un identificador de archivo que representa un objeto de archivo que se utilizará para acceder al archivo para leer, escribir o agregar.

Al abrir un archivo para leerlo, Python necesita saber exactamente cómo debe abrirse el archivo con el sistema. Hay dos modos de acceso disponibles: lectura y lectura en modo binario. Las banderas respectivas utilizadas son r y rb, y deben especificarse al abrir un archivo con el método integrado open(). El primer modo incluye la interpretación de caracteres especiales como "CR" (retorno de carro) y "LF" (salto de línea) para representar saltos de línea, mientras que el modo binario le permite leer los datos en modo sin procesar, donde el los datos se almacenan tal como están sin más interpretación.

Una vez que haya abierto un archivo, el método open() le devolverá un objeto de archivo. Estos objetos de archivo tienen métodos como read(), readline(), write(), tell() y seek(). Si bien algunos objetos de archivo (u objetos similares a archivos) tienen más métodos que los que se enumeran aquí, estos son los más comunes. No todos los objetos de archivo necesitan implementar todos los métodos de archivo.

Ejemplos

En este artículo estaremos explicando cómo leer archivos con Python a través de ejemplos. Algunos ejemplos incluyen leer un archivo línea por línea, como un fragmento (un número definido de líneas a la vez) y leer un archivo de una sola vez. Además, le mostraremos una forma de leer una línea específica del archivo, solo, sin buscar en todo el archivo.

Leer un archivo línea por línea

El primer ejemplo está inspirado en los dos lenguajes de programación C y C++. Es bastante simple, abre el archivo usando el método open(), leer el archivo línea por línea usando readline() método, y la salida de la línea inmediatamente después de la lectura. En uso aquí hay un bucle while que lee continuamente del archivo siempre que el método readline() siga devolviendo datos. En caso de que se alcance el fin del documento (EOF), el bucle while se detiene y el objeto del archivo se cierra, liberando los recursos para otros programas a utilizar.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# define the name of the file to read from
filename = "test.txt"

# open the file for reading
filehandle = open(filename, 'r')
while True:
    # read a single line
    line = filehandle.readline()
    if not line:
        break
    print(line)

# close the pointer to that file
filehandle.close()

Listado 1

Como habrá notado en el Listado 1, hemos abierto y cerrado explícitamente el archivo (líneas 5 y 14, respectivamente). Aunque el intérprete de Python cierra los archivos abiertos automáticamente al final de la ejecución del programa Python, cerrar explícitamente el archivo a través de close() es un buen estilo de programación y no debe olvidarse.

Como mejora, en Python 2.3 se introdujo el conveniente protocolo iterador. Esto le permite simplificar el bucle readline de la siguiente manera:

1
2
3
4
5
# define the name of the file to read from
filename = "test.txt"

for line in open(filename, 'r'):
    print(line)

Listado 2

En uso aquí hay un bucle for en combinación con el iterador in. El archivo se abre en la línea 4 del Listado 2. La línea actual se identifica con la ayuda del iterador in, se lee del archivo y su contenido se envía a stdout en la línea 5. Python cubre la apertura y el cierre del archivo por usted cuando queda fuera del alcance. Si bien es ineficiente, esto le permite no tener que lidiar más con los identificadores de archivos.

Desafortunadamente, el código anterior es menos explícito y se basa en la recolección de basura interna de Python para manejar el cierre del archivo. Introducido en Python 2.5, el comando with encapsula todo el proceso aún más, y también maneja abrir y cerrar archivos solo una vez en todo el bloque de código de alcance. Listado 3 muestra cómo usar el comando with.

1
2
3
4
5
6
# define the name of the file to read from
filename = "test.txt"

with open(filename, 'r') as filehandle:
    for line in filehandle:
        print(line)

Listado 3

La combinación de la instrucción with y el comando open() abre el archivo solo una vez (línea 4). Si tiene éxito, se ejecuta el bucle for y el contenido de la línea se imprime en stdout (líneas 5 y 6).

Además, el uso de la declaración with tiene un efecto secundario. Internamente, el intérprete de Python crea un bloque try-finally para encapsular la lectura del archivo. Listado 4 muestra lo que sucede esencialmente internamente en Python con los bloques de código with:

1
2
3
4
5
try:
    filehandle = open(filename, 'r')
    # do something
finally:
    filehandle.close()

Listado 4

Lectura de un archivo como fragmentos de líneas

Hasta ahora hemos procesado un archivo línea por línea. Esto es bastante lento para archivos grandes y se puede mejorar leyendo varias líneas al mismo tiempo. Para lograrlo, entra en juego el método islice() del módulo itertools. Además, funciona como un iterador y devuelve una porción de datos que consta de n líneas. Al final del archivo, el resultado puede ser más corto y, finalmente, la llamada devolverá una lista vacía.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
from itertools import islice

# define the name of the file to read from
filename = "test.txt"

# define the number of lines to read
number_of_lines = 5

with open(filename, 'r') as input_file:
    lines_cache = islice(input_file, number_of_lines)
   
    for current_line in lines_cache:
        print (current_line)

Listado 5

Leer una línea específica de un archivo

Usando los métodos que se muestran arriba, también podemos realizar otras acciones útiles, como leer una línea específica de un archivo. Para hacer esto, hacemos uso de un contador e imprimimos la línea apropiada cuando llegamos a ella mientras iteramos a través del archivo.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# define the name of the file to read from
filename = "test.txt"

# define the line number
line_number = 3

print ("line %i of %s is: " % (line_number, filename))

with open(filename, 'r') as filehandle:
current_line = 1
    for line in filehandle:
        if current_line == line_number:
            print(line)
            break
        current_line += 1

Listado 6

Listado 6 debería ser fácil de entender, pero es un poco más largo que los ejemplos anteriores. Se puede acortar usando el módulo caché de línea. Listado 7 muestra cómo simplificar el código usando el método getline(). Si el número de línea solicitado cae fuera del rango de líneas válidas en el archivo, entonces el método getline() devuelve una cadena vacía en su lugar.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# import linecache module
import linecache

# define the name of the file to read from
filename = "test.txt"

# define line_number
line_number = 3

# retrieve specific line
line = linecache.getline(filename, line_number)
print ("line %i of %s:" % (line_number, filename))
print (line)

Listado 7

Leer todo el archivo de una vez

Por último, pero no menos importante, veremos un caso muy diferente al ejemplo anterior: leer un archivo completo de una sola vez. Tenga en cuenta que, en la mayoría de los casos, debe tener suficiente espacio en su computadora para leer el archivo completo en la memoria. Listado 8 utiliza una combinación de la instrucción with y el método read(). En este caso, usaremos read() para cargar el contenido del archivo como un flujo de datos.

1
2
3
4
5
6
# define the name of the file to read from
filename = "test.txt"

with open(filename, 'r') as filehandle:
    filecontent = filehandle.read()
    print (filecontent)

Listado 8

Python también ofrece el método readlines(), que es similar al método readline() del primer ejemplo. A diferencia de read(), el contenido del archivo se almacena en una lista, donde cada línea del contenido es un elemento. Listado 9 muestra cómo acceder a esos datos:

1
2
3
4
5
6
7
# define the name of the file to read from
filename = "test.txt"

with open(filename, 'r') as filehandle:
    filecontent = filehandle.readlines()
    for line in filecontent:
        print (line)

Listado 9

Si bien readlines() leerá el contenido del archivo hasta que llegue a EOF, tenga en cuenta que también puede limitar la cantidad de contenido leído proporcionando el parámetro sizehint, que es la cantidad de bytes para leer.

Conclusión

Como es habitual, hay más de una forma de leer el contenido de un archivo. En términos de velocidad, todos ellos están más o menos en la misma categoría. En cuanto a qué solución funciona mejor para usted, depende de su caso de uso específico. Creemos que es bastante útil ver qué es posible y luego elegir la solución que mejor se adapte.

Si bien Python simplifica enormemente el proceso de lectura de archivos, a veces puede volverse complicado, en cuyo caso le recomiendo que consulte la [documentación oficial de Python] (https://docs.python.org/3) /tutorial/inputoutput.html) para obtener más información.

Recursos

Agradecimientos

El autor quisiera agradecer a Zoleka Hatitongwe por su apoyo mientras preparaba el artículo.