-
Introducción
En la clase 15 exploraremos una de las habilidades más importantes para cualquier programador: interactuar con archivos de texto. Esta capacidad permite que los programas puedan almacenar información de forma persistente, leer datos previamente guardados y generar registros automáticos. Para ello, aprenderemos a utilizar la función open() en Python, dominando sus distintos modos de apertura (lectura, escritura y anexado), y entenderemos cómo leer archivos completos o línea por línea, así como escribir y modificar contenido de manera segura. Esta sección introduce también el uso de estructuras como with, que permiten trabajar con archivos garantizando su cierre automático, lo cual es esencial para evitar errores en aplicaciones reales.
Asimismo, abordaremos el manejo de excepciones mediante bloques try, except, else y finally. Estos mecanismos permiten capturar y tratar errores como archivos no encontrados, permisos denegados o problemas de lectura/escritura, de forma que el programa no se detenga abruptamente. Esta parte es clave para desarrollar aplicaciones más estables, profesionales y centradas en la experiencia del usuario. Al finalizar esta clase, estarás en capacidad de leer y escribir archivos de texto eficientemente, y construirás programas más robustos capaces de responder con elegancia ante situaciones imprevistas.
-
15.1. Lectura/escritura de archivos de texto (open(), read(), write()).
El almacenamiento persistente de datos es una necesidad esencial en el desarrollo de software. Los programas no solo deben procesar información en memoria (RAM), sino también guardar datos para poder recuperarlos después de que se cierre el programa. Una forma básica y universal de lograrlo es mediante los archivos de texto.
¿Qué es un archivo de texto?Un archivo de texto es un tipo de archivo que contiene únicamente caracteres legibles por humanos. Cada carácter se representa por un valor codificado (como ASCII o UTF-8), y se organiza generalmente por líneas, con un carácter especial para indicar el salto de línea (por ejemplo, \n).
Los archivos de texto tienen varias características:
- Formato plano: sin estilos ni estructuras complejas.
- Fácil de crear y editar: se pueden abrir con editores como Bloc de notas.
- Utilidad: ideales para almacenar configuraciones, registros (logs), datos simples, etc.
Operaciones básicas: lectura y escrituraEn el contexto computacional, leer y escribir archivos de texto implica la comunicación entre el programa y el sistema de archivos del sistema operativo. Esto se logra a través de flujos de datos (streams) que conectan el programa con el archivo.
- Lectura
La lectura de un archivo de texto consiste en abrir el archivo y copiar su contenido (total o parcial) hacia la memoria del programa para su procesamiento. Puede hacerse de varias formas:
- Leer todo el contenido de una vez.
- Leer línea por línea.
- Leer por bloques (por ejemplo, de 512 caracteres).
- Escritura
La escritura en un archivo de texto es el proceso inverso: enviar información desde el programa hacia el archivo. Según el modo de escritura, se puede:
- Sobrescribir el contenido existente.
- Añadir (anexar) al final del archivo sin eliminar lo anterior.
Ciclo general de lectura/escrituraTodo proceso de entrada/salida de archivos sigue una estructura general:
- Abrir el archivo (indicando nombre y modo de acceso).
- Leer o escribir datos según se requiera.
- Cerrar el archivo para liberar recursos y garantizar que los datos se hayan guardado correctamente.
Consideraciones importantes- Codificación de caracteres: es fundamental especificar cómo están representados los caracteres (por ejemplo, ASCII vs. UTF-8) para evitar errores con símbolos especiales.
- Gestión de errores: los programas deben prever situaciones como archivos inexistentes, permisos denegados o errores de lectura/escritura.
- Persistencia y trazabilidad: la escritura en archivos permite conservar resultados, generar historiales, guardar configuraciones o registrar eventos (logs).
Archivo en PythonPara trabajar con archivos de texto en Python utilizamos la función open(), que nos devuelve un objeto de tipo file. Sus parámetros más comunes son:
- open(ruta, modo, encoding=None)
Cada vez que abrimos un archivo, debemos cerrarlo al terminar, usando file.close() o, de forma más segura, el contexto with.
Trabajar con archivos de texto en Python implica esencialmente tres pasos: abrir el archivo, operar sobre él (leer o escribir), y finalmente cerrarlo para liberar recursos del sistema. A continuación, detallamos cada aspecto:
- open(ruta, modo, encoding=None)
- ruta (str): la ubicación del archivo en tu sistema de archivos.
- modo (str): determina qué operaciones permitimos sobre el archivo:
- "r" Lectura (por defecto). Error si el archivo no existe.
- "w" Escritura: trunca (vacía) el archivo o crea uno nuevo.
- "a" Anexar: abre para escritura al final, sin borrar contenido previo; crea el archivo si no existe.
- "r+" Lectura y escritura; error si no existe, pero no trunca.
- encoding (str, opcional):
- Especifica la codificación de caracteres.
- Recomendado usar "utf-8" para garantizar compatibilidad Unicode.
- Si no lo indicas, Python usará la codificación por defecto de tu sistema (p. ej. "cp1252" en Windows en Español), lo cual puede producir errores de decodificación al leer caracteres especiales.
Código
f_lectura = open("datos.txt", "r", encoding="utf-8") f_escritura = open("salida.txt", "w", encoding="utf-8") f_anexar = open("log.txt", "a", encoding="utf-8") f_lect_escr = open("todo.txt", "r+", encoding="utf-8")
- Operaciones de lectura
Una vez tenemos el objeto file, podemos:
-
Leer todo de una vez
Código
contenido = f.read() # Lee hasta el final. Útil para archivos pequeños (< 10 MB).
-
Leer por bloques
Código
fragmento = f.read(100) # Hasta 100 caracteres. Continua desde la posición actual.
-
Leer línea a línea
Código
linea = f.readline() # Lee hasta el siguiente "\n". lineas = f.readlines() # Devuelve una lista de todas las líneas.
-
Iterar sobre el archivo
Código
for linea in f: process(linea)
-
Leer todo de una vez
Interno: Python maneja un búfer en memoria que agrupa lecturas al sistema operativo, reduciendo llamadas a disco y mejorando el rendimiento.
- Operaciones de escritura
Para escribir texto:
-
write()
Código
n = f.write("Hola, mundo\n") # Devuelve el número de caracteres escritos.
-
writelines()
Código
lineas = ["Primera línea\n", "Segunda línea\n"] f.writelines(lineas) # Escribe cada cadena, sin añadir "\n" automático.
-
flush() (opcional)
Código
f.flush() # Fuerza a vaciar el búfer a disco sin cerrar el archivo.
Atención: En modo "w" cualquier contenido previo se pierde al abrir.
-
write()
- Cierre del archivo
Siempre que abras un archivo, debes cerrarlo para:
- Liberar el descriptor de archivo (recurso limitado del sistema operativo).
- Asegurar que todo el búfer de escritura se grabe en disco.
-
Cierre manual
Código
f = open("archivo.txt", "r", encoding="utf-8") # ... leer o escribir ... f.close()
-
Uso de contexto (with)
La forma más segura y recomendada es usar un context manager:Código
with open("archivo.txt", "r", encoding="utf-8") as f: datos = f.read() # Aquí f.close() se invoca automáticamente, incluso si ocurre una excepción
Figura 1: Flujo de Apertura de un Archivo para Lectura Fuente: Creación de autor, D. Nicolalde. Figura 1: Flujo de Apertura de un Archivo para Lectura Fuente: Creación de autor, D. Nicolalde.
Descripción: Ilustra cómo open() crea un objeto file en modo lectura.
Ejemplo: Escritura y Lectura SimplesCódigo
# Escritura with open("datos.txt", "w", encoding="utf-8") as f: f.write("Hola, mundo!\n") f.write("Segunda línea.\n") # Lectura with open("datos.txt", "r", encoding="utf-8") as f: contenido = f.read() print(contenido)
En este ejemplo, abrimos el archivo datos.txt (si no existe se crea en el directorio raíz) en modo escritura ("w") dentro de un bloque with, lo que crea o sobrescribe el archivo y automáticamente lo cierra al terminar; dentro del bloque usamos f.write() para volcar dos líneas de texto con saltos de línea. A continuación, lo volvemos a abrir en modo lectura ("r") también con with, leemos todo su contenido de una vez con f.read() y lo imprimimos, obteniendo en pantalla exactamente las dos líneas que habíamos escrito. Este patrón garantiza un manejo seguro y conciso de la apertura, escritura, lectura y cierre del archivo.
Figura 2: Flujo de Lectura Completa de un Archivo Fuente: Creación de autor, D. Nicolalde. Figura 2: Flujo de Lectura Completa de un Archivo Fuente: Creación de autor, D. Nicolalde.
Descripción: Representa f.read() que extrae todo el contenido.
Ejemplo: Lectura Línea a LíneaCódigo
with open("datos.txt", "r", encoding="utf-8") as f: for linea in f: print(">>", linea.strip())
Este ejemplo abre el archivo datos.txt en modo lectura ("r") y, usando el contexto with, garantiza que el archivo se cierre automáticamente al terminar. Luego recorre el objeto fichero f línea a línea: en cada iteración, la variable linea contiene una cadena con una línea completa (incluyendo el salto de línea). Al aplicar linea.strip(), se eliminan espacios y saltos de línea al principio y al final, y con print(">>", …) se muestra cada línea limpiada precedida de los caracteres >>, lo que facilita identificar visualmente cada registro leído.
Figura 3: Flujo de Iteración Línea a Línea Fuente: Creación de autor, D. Nicolalde. Figura 3: Flujo de Iteración Línea a Línea Fuente: Creación de autor, D. Nicolalde.
Descripción: Muestra for linea in f para procesar cada línea.
Ejemplo: Anexar Registros de LogCódigo
import datetime def log_evento(mensaje): timestamp = datetime.datetime.now().isoformat() with open("app.log", "a", encoding="utf-8") as log: log.write(f"[{timestamp}] {mensaje}\n") log_evento("Inicio de la aplicación.") log_evento("Operación completada.")
Este ejemplo muestra cómo anexar (añadir) registros a un archivo de log utilizando Python. Primero, la función log_evento(mensaje) genera una marca de tiempo (timestamp) utilizando la fecha y hora actuales mediante datetime.datetime.now().isoformat(). Luego, abre el archivo "app.log" en modo de anexar ("a"), asegurando que los nuevos mensajes se añadan al final sin sobrescribir lo anterior. Finalmente, se escriben líneas en el archivo que incluyen la marca de tiempo y el mensaje proporcionado, generando un historial claro de eventos que ayuda en tareas como depuración y auditoría.
Figura 4: Flujo de Escritura en Modo Anexar ("a") Fuente: Creación de autor, D. Nicolalde. Figura 4: Flujo de Escritura en Modo Anexar ("a") Fuente: Creación de autor, D. Nicolalde.
Descripción: Ilustra cómo open(..., "a") añade sin borrar.
Ejemplo: Procesamiento de Gran VolumenCódigo
def contar_palabras(archivo): conteo = {} try: with open(archivo, "r", encoding="utf-8") as f: for linea in f: for palabra in linea.split(): conteo[palabra] = conteo.get(palabra, 0) + 1 return conteo except FileNotFoundError: print(f"Error: {archivo} no encontrado.") return {}
Este ejemplo presenta una solución eficiente para contar palabras en archivos de texto grandes, ideal cuando se trabaja con archivos que no pueden cargarse completamente en memoria. La función contar_palabras() abre el archivo con open() en modo lectura ("r") y codificación UTF-8. Usando un ciclo for, recorre línea por línea (lo que ahorra memoria), y cada línea se divide en palabras mediante split(). Luego, se utiliza un diccionario llamado conteo para registrar cuántas veces aparece cada palabra, incrementando su contador con conteo.get(palabra, 0) + 1, una forma eficiente de manejar claves nuevas o ya existentes.
Además, el uso del bloque try/except garantiza que el programa sea robusto ante errores comunes. En particular, si el archivo especificado no se encuentra, se lanza una excepción FileNotFoundError, y en lugar de interrumpir el programa, se imprime un mensaje de advertencia y se retorna un diccionario vacío. Esta práctica protege al sistema de fallos y permite que otros procesos continúen normalmente. En conjunto, este ejemplo enseña cómo combinar lectura eficiente de archivos, estructuras de datos como diccionarios y manejo de excepciones para construir herramientas útiles y resilientes para el análisis de texto.
Figura 5: Flujo de Procesamiento con Excepciones Fuente: Creación de autor, D. Nicolalde. Figura 5: Flujo de Procesamiento con Excepciones Fuente: Creación de autor, D. Nicolalde.
La tabla 1 Resume los modos de open() y sus usos típicos.
Modo Descripción Ejemplo de Uso r Lectura, error si no existe open("f.txt", "r") w Escritura, crea o sobrescribe open("f.txt", "w") a Anexar al final, crea si no existe open("f.txt", "a") r+ Lectura y escritura open("f.txt", "r+") x Creación exclusiva, error si existe open("f.txt", "x") Tabla 1: Modos de Apertura de Archivos en Python Modo: rDescripción: Lectura, error si no existe
Ejemplo: open("f.txt", "r")
Modo: wDescripción: Escritura, crea o sobrescribe
Ejemplo: open("f.txt", "w")
Modo: aDescripción: Anexar al final, crea si no existe
Ejemplo: open("f.txt", "a")
Modo: r+Descripción: Lectura y escritura
Ejemplo: open("f.txt", "r+")
Modo: xDescripción: Creación exclusiva, error si existe
Ejemplo: open("f.txt", "x")
Aprende más
Este video explica de forma clara y didáctica cómo leer y escribir archivos de texto en Python usando open(), read(), write() y with. ¡Accede aquí!
-
15.2. Manejo de excepciones (try-catch).
Durante la ejecución de un programa, pueden surgir situaciones imprevistas que impidan que el programa continúe con su flujo normal. Estos eventos pueden deberse a errores humanos (como introducir letras en lugar de números), problemas del entorno (como intentar abrir un archivo que no existe), o situaciones imprevistas en tiempo de ejecución (como dividir por cero). Si estas situaciones no se manejan correctamente, el programa se interrumpe de forma abrupta, lo que representa una mala experiencia para el usuario y una falta de robustez del software.
Para resolver esto, los lenguajes de programación modernos —como Python, Java o C++— incluyen estructuras especiales de control de errores. En Python, estas estructuras se denominan bloques try-except. En otros lenguajes como Java o C#, se llaman try-catch.
¿Qué es una excepción?Una excepción es una señal enviada por el sistema cuando ocurre un error durante la ejecución de un programa. Es decir, es un evento excepcional que rompe el flujo normal del código. Las excepciones no son errores de sintaxis (que se detectan antes de ejecutar), sino errores que surgen mientras el programa está corriendo.
Algunos ejemplos comunes de excepciones en tiempo de ejecución:
- FileNotFoundError: Cuando se intenta abrir un archivo que no existe.
- ZeroDivisionError: Al intentar dividir un número entre cero.
- ValueError: Si se intenta convertir una letra en número (ej. int("a")).
- PermissionError: Acceso denegado al intentar abrir o modificar un archivo.
- IndexError: Acceso a una posición inexistente en una lista o arreglo.
Por ejemplo:
Código
f = open("archivo_que_no_existe.txt", "r")
Este código lanza una excepción tipo FileNotFoundError porque el archivo no existe. Si no hacemos nada, el programa se detiene con un mensaje de error.
¿Qué es un bloque try-except?Es una estructura de control que permite intentar ejecutar un bloque de código, y en caso de que ocurra un error, atrapar ese error (la excepción) y decidir cómo actuar.
Código
try: # Código que puede lanzar una excepción except TipoDeError: # Código que se ejecuta si ocurre ese error
Ejemplo:Código
try: f = open("datos.txt", "r") contenido = f.read() f.close() except FileNotFoundError: print("El archivo no existe.")
Componentes adicionales del manejo de excepcionesPython también permite agregar bloques opcionales:
- else: Se ejecuta si no ocurre ninguna excepción. Es útil para separar el código seguro del arriesgado.
- finally: Se ejecuta siempre, ocurra o no una excepción. Ideal para liberar recursos (cerrar archivos, conexiones, etc.).
El uso de bloques try-except es fundamental cuando trabajamos con archivos, entradas de usuario, o cualquier recurso que pueda fallar. Es una herramienta poderosa que permite construir programas más profesionales, seguros y amigables para el usuario.
Figura 6: Flujo de Estructura try/except/finally Fuente: Creación de autor, D. Nicolalde. Figura 6: Flujo de Estructura try/except/finally Fuente: Creación de autor, D. Nicolalde.
Descripción: Muestra las fases de ejecución y manejo de errores.
Código
try: with open("config.txt", "r", encoding="utf-8") as cf: datos = cf.read() except FileNotFoundError: print("No se encontró config.txt; usando valores por defecto.") datos = "" except PermissionError: print("Permiso denegado al abrir config.txt.") datos = "" else: print("Archivo leído exitosamente.") finally: print("Bloque finally: recursos liberados.")
Este código ejemplifica el manejo robusto de errores al intentar leer un archivo llamado config.txt en Python. Utiliza la estructura try/except/else/finally para controlar el flujo de ejecución frente a posibles fallos:
- Bloque try: Intenta abrir config.txt en modo lectura ("r") con codificación UTF-8. Si tiene éxito, su contenido se almacena en la variable datos.
- except FileNotFoundError: Si el archivo no existe, se captura este error específico. Se imprime un mensaje y datos se define como una cadena vacía.
- except PermissionError: Si el programa no tiene permisos para acceder al archivo, este bloque captura el error, imprime un mensaje y también asigna datos como vacío.
- else: Si no ocurre ninguna excepción, se imprime un mensaje indicando que la lectura fue exitosa.
- finally: Este bloque se ejecuta siempre, haya habido o no un error. Aquí se indica que los recursos han sido liberados, reforzando buenas prácticas como el cierre implícito del archivo.
Este patrón es útil para mantener el programa estable frente a errores comunes de E/S, como archivos faltantes o restricciones de permisos.
En la tabla 2 se enumera errores frecuentes y su significado.
Excepción Descripción Cuándo ocurre FileNotFoundError Archivo no existe open("noexiste.txt", "r") PermissionError Permiso insuficiente para acceder o modificar archivo Acceso a archivo protegido IOError Error genérico de E/S Fallos en disco, interrupciones de I/O ValueError Modo de apertura inválido open("f.txt", "z") Tabla 2: Excepciones Comunes en Operaciones de Archivos FileNotFoundErrorDescripción: Archivo no existe
Cuándo ocurre: open("noexiste.txt", "r")
PermissionErrorDescripción: Permiso insuficiente para acceder o modificar archivo
Cuándo ocurre: Acceso a archivo protegido
IOErrorDescripción: Error genérico de E/S
Cuándo ocurre: Fallos en disco, interrupciones de I/O
ValueErrorDescripción: Modo de apertura inválido
Cuándo ocurre: open("f.txt", "z")
Ejemplo: Gestor de Tareas en ArchivoCódigo
def agregar_tarea(tarea): try: with open("tareas.txt", "a", encoding="utf-8") as tf: tf.write(tarea + "\n") except IOError as e: print("Error al escribir en tareas.txt:", e) def listar_tareas(): try: with open("tareas.txt", "r", encoding="utf-8") as tf: return [l.strip() for l in tf] except FileNotFoundError: return [] # Uso agregar_tarea("Aprender archivos en Python") agregar_tarea("Practicar manejo de excepciones") print("Tareas pendientes:") for t in listar_tareas(): print(" -", t)
Este ejemplo presenta un gestor de tareas simple en Python que permite guardar y leer tareas desde un archivo de texto (tareas.txt). La función agregar_tarea() añade nuevas tareas utilizando open() en modo "a" (anexar), lo que garantiza que las tareas anteriores no se pierdan. Se usa la estructura with open(...) para abrir el archivo de forma segura y se implementa un bloque try/except para capturar errores de escritura como IOError. Por otro lado, la función listar_tareas() abre el archivo en modo lectura y devuelve una lista con las tareas, eliminando los saltos de línea. Si el archivo no existe, se captura la excepción FileNotFoundError y se retorna una lista vacía.
Este enfoque combina manipulación de archivos de texto con manejo de excepciones, permitiendo que el programa funcione correctamente incluso en condiciones adversas, como archivos inexistentes o errores de permisos. Además, enseña buenas prácticas como el uso de with para la gestión automática de recursos y el uso de listas por comprensión para procesar líneas. Es una excelente introducción a programas reales que requieren almacenamiento persistente y una estructura de control robusta..
Salida esperadaResultado
Tareas pendientes: - Aprender archivos en Python - Practicar manejo de excepciones
Al finalizar esta clase, los estudiantes habrán adquirido las competencias para interactuar con archivos de texto de forma segura y eficiente, y para construir aplicaciones resilientes ante errores de E/S.
Aprende más
En este vídeo del curso de Python, veremos el control de las excepciones con Try, except y finally. ¡Accede aquí!
Profundiza más
Este recurso te ayudará a enfatizar sobre Funciones y archivo de texto ¡Accede aquí!
-
-
-
Actividades
-
Make a submission
-
Make attempts: 1
-
Funciones y archivos de texto
-
Make a submission
-
Make attempts: 1