Introducción a la programación en Python

clase 07a
Escritura y lectura de archivos

Hay muchas formas de presentar la salida de un programa y en algunos casos conviene escribirla a un archivo. A su vez, los datos a procesar pueden ser extraídos también desde un archivo existente. A continuación veremos algunas de las funciones provistas por el lenguaje para escritura y lectura de archivos.

open()

La función open() devuelve un objeto del tipo file (i.e. archivo), que se puede asignar a una variable.

f = open('./tmp/archivo.ext', 'w')

La función open recibe dos argumentos: nombre de archivo y modo.

El primer argumento es una cadena de caracteres que indica el nombre de archivo que se va a abrir. El segundo argumento es opcional, y es otra cadena de caracteres, que describe el modo en que se abrirá el archivo y el formato de sus datos.

Hay diversos modos de abrir un archivo:

'r' modo de solo lectura, no se puede escribir (modo por defecto). Si el archivo no existe, devuelve un error.
'w' modo de solo escritura. Si existe un archivo con el mismo nombre, se borra, y si no existe, se crea.
'a' modo de agregado (append), los datos escritos se agregan al final del archivo. Si el archivo no existe, se crea.
'x' se crea el archivo para escritura. Si ya existe, devuelve un error.
'r+' el archivo se abre para lectura y escritura al mismo tiempo.

Adicionalmente, se puede especificar si el archivo se va a manejar en modo texto o binario.

't' modo texto (modo por defecto).
'b' modo binario, para almacenar cualquier otro tipo de datos que no sean texto

Por defecto, los archivos se abren en modo lectura ("r") y texto ("t"). Por lo tanto, la siguiente instrucción:

f = open('./tmp/archivo.ext')

es equivalente a:

f = open('./tmp/archivo.ext', 'rt')

Los objetos de tipo file tienen varios métodos para leer y escribir sus datos.

f.read()

La función read(size) permite leer el contenido del archivo. El argumento size es opcional y si no se especifica (o es -1) devuelve el contenido de todo el archivo. Una vez que se leyó todo el archivo, una nueva llamada a la función devuelve un string vacío ('').

In [1]:
f = open('./tmp/archivo_una_linea.txt')
f.read()
Out[1]:
'Esto es todo el archivo\n'

f.readline()

Lee una sola línea del archivo, devuelve al final de la línea el caracter de nueva línea (\n) y solo se omite en la última línea del archivo (si no termina con el caracter de nueva línea). Esto hace que el valor de retorno no sea ambiguo. Si retorna una cadena de caracteres vacía se alcanzó el fin del archivo, mientras que una línea en blanco se representa con un caracter de nueva línea (\n).

In [13]:
f = open('./tmp/archivo_dos_lineas.txt')
print(f.readline())
print(f.readline())
print(f.readline())
Esta es la primera línea del archivo.

Y esta es la segunda línea.

f.readlines()

Devuelve una lista que contiene todas las líneas del archivo.

In [15]:
f = open('./tmp/archivo_tres_lineas.txt')
lines = f.readlines()
print(lines)
['Esta es la primera línea del archivo.\n', 'Esta es la segunda línea.\n', 'Esta es la tercera y última línea.\n']

Una forma más rápida de leer todas las líneas de un archivo, y más eficiente en cuanto a la memoria, es con un bucle de repetición que recorra cada línea del archivo.

In [16]:
f = open('./tmp/archivo_tres_lineas.txt')
for line in f:
    print(line, end='')
Esta es la primera línea del archivo.
Esta es la segunda línea.
Esta es la tercera y última línea.

f.write(s)

Escribe el contenido de la cadena de caracteres *s* al archivo, y devuelve la cantidad de caracteres escritos.

Para escribir algo que no sea de tipo cadena de caracteres, antes se debe convertir a cadena de caracteres.

In [ ]:
f = open('./tmp/archivo_nuevo.txt','w')
f.write('Esto es una prueba\n')

valor = ('LA4', 440)
s = str(valor)
f.write(s)

f.close()

Una vez que se terminó de usar el archivo es necesario cerrarlo, para liberar los recursos tomados por el manejo del archivo. Eso se hace con la instrucción *f*.close(), luego de lo cual una invocación a la función *f*.read() devuelve un error, porque el archivo está cerrado.

In [4]:
f = open('./tmp/archivo_dos_lineas.txt')
f.close()
f.read()
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-4-3de77cd9df0c> in <module>
      1 f = open('./tmp/archivo_dos_lineas.txt')
      2 f.close()
----> 3 f.read()

ValueError: I/O operation on closed file.

with

Una buena práctica para el manejo de archivos es el uso de la palabra clave with, porque tiene la ventaja de que el archivo se cierra correctamente sin necesidad de preocuparnos por ello, incluso cuando ocurre un error y se lanza una excepción.

In [1]:
with open('./tmp/archivo_dos_lineas.txt', 'r') as f:
    datos = f.read()
print(datos)
f.closed
Esta es la primera línea del archivo.
Y esta es la segunda línea.
Out[1]:
True

El módulo os

Desde Python se pueden utilizar funciones del sistema operativo, importanto el módulo externo os.

Entre las numerosas funciones que ofrece este módulo, se incluyen algunas relacionadas al manejo de archivos y directorios, como borrar un archivo o verificar si existe.

os.path.exists()

Esta función recibe como argumento una cadena de caracteres, y devuelve la varable booleana True si existe un archivo con ese nombre, o False en caso contrario.

La ruta (path) del archivo puede ser absoluta, o relativa al directorio donde está corriendo el programa.

In [12]:
import os
os.path.exists("tmp/archivo_una_linea.txt")
Out[12]:
True
In [13]:
os.path.exists("foo.txt")
Out[13]:
False

os.remove()

Esta función también recibe como argumento una cadena de caracteres. Si existe un archivo con ese nombre, lo borra, y en caso contrario devuelve un error.

In [14]:
os.remove("foo.txt")
---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
<ipython-input-14-a829cc9f95ea> in <module>
----> 1 os.remove("foo.txt")

FileNotFoundError: [Errno 2] No such file or directory: 'foo.txt'

Se pueden combinar ambas funciones para verificar si un archivo existe antes de intentar borrarlo, y evitar el error.

In [15]:
if os.path.exists("foo.txt"):
    os.remove("foo.txt")
else:
    print("El archivo no existe") 
El archivo no existe

Se pueden ver todas las funciones que provee este módulo, consultando la documentación oficial: https://docs.python.org/3/library/os.html.