- Aprender
- Informática
- Programación
- Introducción a la programación con Python
- Archivos y excepciones en Python
Archivos y excepciones en Python
with y localiza archivos mediante rutas relativas y absolutas y pathlib. Lee y escribe datos CSV con el módulo csv, incluidas filas como diccionarios. Después, captura los errores que esperas con try y except, usa else y finally, lanza tus propias excepciones con mensajes claros y crea programas que informen de archivos ausentes y datos incorrectos en lugar de cerrarse por un error.PrincipianteUnidad 8 de 10 del curso Curso de Introducción a la programación con Python
Lo que aprenderás
- Abre archivos de texto, lee su contenido de la forma adecuada para cada tarea, escribe y añade texto sin perder datos y procesa un archivo línea a línea para buscar, contar y filtrar.
- Abre un archivo de texto y lee su contenidoUsa
open()para conectar un programa con un archivo de texto, elige la forma adecuada de leerlo y convierte el texto leído en datos que puedas usar. - Cierra archivos automáticamente con la sentencia withUsa
with open(...) as f:para que los archivos se cierren en el momento adecuado, incluso cuando algo salga mal. - Escribe y añade texto a archivosElige el modo adecuado para crear, sobrescribir o ampliar un archivo y escribe texto con
write()yprint()para que las líneas queden exactamente como quieres. - Busca, cuenta y filtra líneas de un archivoProcesa un archivo línea a línea para encontrar las líneas que necesitas, contarlas o sumar sus valores y escribir los resultados en un archivo nuevo.
- Abre un archivo de texto y lee su contenido
- Indica a Python exactamente dónde está un archivo, comprende por qué a veces un programa no encuentra un archivo que existe y construye rutas que funcionen en Windows, macOS y Linux.
- Usa correctamente rutas relativas y absolutasEscribe rutas absolutas y relativas, identifica desde qué carpeta parte una ruta relativa y evita los problemas de las barras invertidas en las rutas de Windows.
- Construye rutas y gestiona carpetas con pathlibUsa objetos
Pathdel módulopathlibpara unir, examinar y comprobar rutas, localizar archivos, crear carpetas y leer o escribir archivos pequeños en un solo paso.
- Usa correctamente rutas relativas y absolutas
- Usa el módulo
csvde Python para leer datos de tablas en archivos CSV, convertirlos en números y escribir los resultados como CSV que puedan abrir los programas de hojas de cálculo.- Lee datos CSV con csv.readerComprende cómo almacena una tabla un archivo CSV, léelo fila a fila con
csv.reader, salta la cabecera y convierte los valores que necesitas. - Escribe archivos CSV con csv.writerCrea archivos CSV a partir de listas con
csv.writerpara que las comas, las comillas y los terminadores de línea se gestionen correctamente. - Trabaja con columnas por su nombre mediante DictReader y DictWriterLee cada fila CSV como un diccionario cuyas claves proceden de la cabecera, filtra y resume filas por nombre de columna y vuelve a escribir los diccionarios como CSV.
- Lee datos CSV con csv.reader
- Reconoce las excepciones que lanza Python, lee una traza de excepción para encontrar la causa, captura los errores que esperas y mantén el programa en ejecución o detenlo con un mensaje claro en lugar de un cierre por error.
- Reconoce excepciones habituales y lee una traza de excepciónComprende qué es una excepción, lee una traza de excepción de abajo arriba y nombra los tipos de excepción habituales y sus causas típicas.
- Captura excepciones con try y exceptEscribe bloques
tryyexceptque capturen los errores específicos que esperas, den al usuario un mensaje útil y permitan que los errores inesperados sigan mostrándose. - Usa else y finally y sigue la propagación de excepciones entre funcionesCompleta una sentencia
tryconelseyfinally, predice el orden en que se ejecutan sus bloques y decide en qué función debe manejarse una excepción. - Gestiona de forma controlada los fallos de programas que trabajan con archivos y datosCombina el manejo de archivos y excepciones para que los archivos ausentes o bloqueados y los datos incorrectos produzcan mensajes claros, filas omitidas o una detención controlada, en lugar de un cierre por error.
- Reconoce excepciones habituales y lee una traza de excepción
- Usa
raisepara impedir que una función continúe con datos de entrada incorrectos, elige tipos de excepción y mensajes adecuados y propaga los errores o conviértelos en otros más claros.- Lanza excepciones para rechazar datos de entrada no válidosUsa la sentencia
raisepara indicar que una función recibió un valor con el que no puede trabajar y deja que el código que la llamó decida cómo responder. - Relanza y encadena excepciones y define excepciones personalizadasPropaga una excepción después de reaccionar a ella, convierte un error de bajo nivel en otro más claro y crea tus propios tipos de excepción para problemas específicos de tu programa.
- Lanza excepciones para rechazar datos de entrada no válidos
Guía de estudio de Archivos y excepciones en Python
1Lee y escribe archivos de texto
Los archivos permiten a un programa conservar información entre ejecuciones y trabajar con datos recopilados en otro lugar. La lectura lleva texto a la memoria; la escritura guarda resultados para la siguiente ejecución o para otra persona. Elegirás un método de lectura, controlarás exactamente lo que se escribe y usarás la sangría para mantener los archivos abiertos solo mientras se necesitan. Después, los ejemplos línea a línea combinan operaciones con cadenas, decisiones y contadores para convertir texto sin procesar en resultados útiles.
1.1 Lectura de texto en un programa
Un archivo de texto conserva la información después de que un programa se detenga. Python usa un objeto de archivo, devuelto por open(), para trabajar con esa información. La apertura conecta con el archivo; una operación de lectura recupera su texto.
Elige qué leer
El modo predeterminado es "r", de lectura. Un nombre sin ruta se busca en el directorio de trabajo actual. Si no se encuentra allí, open() lanza FileNotFoundError.
with open("fruit.txt", encoding="utf-8") as f:
text = f.read()
Supón que el archivo tiene tres líneas, «apple», «banana» y «cherry», todas con terminador de línea. text es 'apple\nbanana\ncherry\n'. La secuencia de escape \n representa un carácter de salto de línea. La última línea también puede terminar sin un salto de línea.
| Operación | Resultado | Útil cuando |
|---|---|---|
f.read() | Todo el texto restante como una cadena | Necesitas un archivo pequeño completo |
f.readline() | La siguiente línea como cadena | Necesitas una línea en ese momento |
f.readlines() | Todas las líneas restantes como lista | Necesitas reutilizar las líneas |
for line in f: | Una línea por iteración | Puedes procesar las líneas en orden |
readline() devuelve '' al final del archivo. Una línea en blanco con terminador de línea devuelve '\n', por lo que una línea en blanco y el final del archivo son distintos.
Sigue la posición
La lectura hace avanzar la posición en el archivo. Después de que f.read() haya consumido el archivo, otra llamada devuelve ''; un bucle sobre ese mismo objeto ya no tiene nada que recorrer. Vuelve a abrir el archivo para empezar de nuevo o conserva el texto o las líneas que necesites en una variable. read() y readlines() cargan en memoria lo que queda del archivo. Recorrer directamente el archivo permite procesar un archivo grande línea a línea.
Las líneas conservan sus caracteres de salto de línea. print(line) añade su propio salto, lo que puede dejar líneas en blanco adicionales en pantalla. Usa print(line, end="") para mantener el espaciado original o elimina el terminador de línea antes de imprimir. line.rstrip("\n") elimina los saltos de línea finales; line.strip() también elimina los espacios de ambos extremos.
Convierte el texto en números
Incluso los dígitos llegan como cadenas. Este archivo contiene las puntuaciones «72», «85» y «90»:
scores = []
with open("scores.txt", encoding="utf-8") as f:
for line in f:
scores.append(int(line))
total = sum(scores)
print(total, round(total / len(scores), 2))
La lista es [72, 85, 90], por lo que el programa imprime 247 82.33. int() acepta espacios y saltos de línea alrededor. Una cadena vacía o una palabra como "forty" lanza ValueError.
Lee los caracteres con la codificación correcta
Una codificación relaciona los caracteres con los bytes almacenados. UTF-8 puede representar caracteres como «é» y emojis. Usa encoding="utf-8" de forma explícita para los archivos UTF-8. Python 3.15 activa el modo UTF-8 de forma predeterminada; las instalaciones anteriores pueden usar una codificación local. Una codificación incorrecta puede producir texto ilegible o UnicodeDecodeError. Indicar la codificación explícitamente no convierte en UTF-8 un archivo guardado con otra codificación.
El bloque with cierra el archivo cuando termina. Un archivo cerrado no se puede leer: otro f.read() lanza ValueError.
Puntos clave
open()devuelve un objeto de archivo; la lectura recupera texto desde su posición actual.- Elige una cadena, una lista de líneas o un bucle línea a línea según la tarea.
- El final del archivo da
''; una línea en blanco puede dar'\n'. - Convierte el texto numérico con
int()ofloat()antes de calcular. - Usa la codificación que corresponda al archivo y ciérralo al terminar.
1.2 Archivos que se cierran al terminar el bloque
Un archivo abierto utiliza recursos del sistema operativo. El texto que se está escribiendo también puede esperar en una memoria intermedia antes de llegar al archivo. Cerrar libera los recursos y vuelca la salida pendiente de esa memoria. Una sentencia with organiza esa liberación en un punto claro del código.
Lee dentro y usa el resultado después
with open("notes.txt", encoding="utf-8") as f:
text = f.read()
print(len(text))
Los dos puntos inician el bloque. La línea con sangría se ejecuta mientras f está abierto. Cuando la ejecución llega al print() sin sangría, el archivo ya se ha cerrado, pero text sigue siendo una cadena normal. El nombre f aún hace referencia al objeto de archivo; ahora f.closed es True.
El mismo patrón sirve para una lista:
with open("fruit.txt", encoding="utf-8") as f:
lines = f.readlines()
for line in lines:
print(line.strip().upper())
El bucle usa datos ya leídos y guardados en lines. Mover f.readlines() fuera del bloque intentaría leer un archivo cerrado y lanzaría ValueError.
Libera recursos cuando la ejecución cambia de dirección
Considera una función que devuelve la primera línea:
def first_line(path):
with open(path, encoding="utf-8") as f:
return f.readline().rstrip("\n")
El valor de retorno se prepara dentro del bloque. Después, Python sale del bloque y cierra el archivo antes de que el código que realizó la llamada reciba ese valor. El archivo también se cierra cuando una excepción sale del bloque. Nunca se llegaría a un f.close() manual situado después de una sentencia que falla.
Los objetos de archivo admiten este comportamiento porque son gestores de contexto: objetos que organizan la preparación y la liberación de recursos en torno a un bloque with. Puedes usar ese comportamiento sin escribir tu propio gestor de contexto.
Abre juntos un archivo de entrada y otro de salida
with open("in.txt", encoding="utf-8") as src, open("out.txt", "w", encoding="utf-8") as dst:
for line in src:
dst.write(line.upper())
Cada línea de entrada se convierte en mayúsculas y se escribe en la salida. Ambos archivos se cierran cuando termina el bloque. Si falla la segunda apertura, el primer archivo, ya gestionado por with, se cierra cuando Python sale de la sentencia.
Liberar recursos y recuperarse de errores cumplen funciones distintas
with no captura los errores de archivo. Si open() no encuentra notes.txt, lanza FileNotFoundError antes de ejecutar el cuerpo. Si la conversión de una línea con int() falla dentro del cuerpo, el archivo se cierra y la excepción sigue propagándose hacia fuera. Se necesita una cláusula except coincidente para recuperarse o mostrar un mensaje.
La ausencia de los dos puntos al final de la línea de with provoca SyntaxError.
Puntos clave
withcierra un archivo abierto al salir normalmente, al retornar y al salir por una excepción.- Las cadenas y listas almacenadas siguen siendo utilizables después de cerrar el archivo.
- La sangría delimita el tiempo durante el que el archivo permanece abierto.
- Liberar recursos no captura una excepción; para recuperarse hacen falta
tryyexcept.
1.3 Creación, sustitución y adición de texto al final
La escritura empieza con una decisión sobre los datos existentes. El modo controla si Python lee, sustituye, amplía o crea un archivo. Decide antes de llamar a open(), porque la sustitución ocurre de inmediato.
Elige el modo
| Modo | Archivo existente | Archivo inexistente |
|---|---|---|
"r" | Lo abre para leer | Lanza FileNotFoundError |
"w" | Lo vacía y después lo abre para escribir | Lo crea |
"a" | Añade la salida al final | Lo crea |
"x" | Lanza FileExistsError | Lo crea |
Abrir la única copia de datos importantes con "w" destruye su contenido anterior aunque no se ejecute después ningún write(). Usa un archivo de salida separado mientras aprendes a transformar datos. "x" es útil cuando se debe impedir la sustitución de un archivo existente.
Añadir "b", como en "rb", selecciona el modo binario para bytes sin procesar. Los modos de texto trabajan con cadenas y una codificación; los modos binarios no aceptan el argumento encoding.
Decide dónde terminan las líneas
with open("todo.txt", "w", encoding="utf-8") as f:
f.write("buy milk\n")
f.write("call Sam\n")
El archivo tiene las dos líneas «buy milk» y «call Sam». write() añade exactamente la cadena recibida, sin ningún separador automático. Sin los saltos de línea, el archivo contendría "buy milkcall Sam" en una sola línea.
write() devuelve el número de caracteres escritos. Por ejemplo, f.write("Ana,92\n") devuelve 7. Es un conteo de caracteres, no necesariamente el número de bytes codificados en disco. Acepta una cadena; f.write(42) lanza TypeError. Convierte primero los números, por ejemplo con f.write(f"{score}\n").
Compara las funciones de ayuda para la salida
print() puede escribir en un archivo:
with open("total.txt", "w", encoding="utf-8") as f:
print("Total:", 247, file=f)
El texto de salida es "Total: 247\n". print() convierte sus argumentos, los separa con espacios y añade un salto de línea final de forma predeterminada.
writelines() recibe una secuencia de cadenas, pero no inserta terminadores de línea. f.writelines(["a", "b"]) escribe "ab". Para obtener un elemento por línea, incluye un salto de línea en cada cadena o une las cadenas con "\n" y añade un salto de línea final.
Conserva las ejecuciones anteriores
with open("log.txt", "a", encoding="utf-8") as f:
f.write("Program started\n")
Si al principio no existe el archivo, dos ejecuciones producen dos líneas. Con "w", cada ejecución sustituiría la entrada anterior. El modo de adición al final no añade un salto de línea ausente: si el texto existente termina a mitad de una línea, el texto nuevo empieza inmediatamente después.
Para un informe, recorre pares como [("Ana", 92), ("Ben", 78)] y escribe f"{name}: {score}\n". El formato se aplica antes de escribir, por lo que f"{82.333:.1f}" produce el texto "82.3". Después, al terminar el bloque, with cierra la salida y vuelca el texto pendiente de la memoria intermedia.
Puntos clave
"w"vacía un archivo existente en cuanto lo abre."a"añade al final;"x"impide sustituir un archivo existente.write()recibe una cadena y no añade ningún salto de línea.print(..., file=f)convierte los valores y añade un salto de línea de forma predeterminada.writelines()escribe cadenas consecutivas sin añadir separadores.- Los modos binarios leen o escriben bytes y no aceptan un argumento de codificación.
1.4 Búsqueda y guardado de líneas útiles
Muchas tareas con archivos consisten en un bucle con una decisión dentro. Lee una línea, elimina los espacios que sobren, decide si interesa y actualiza un resultado. Mantener estos pasos separados facilita comprobar un programa.
Procesa un registro de actividad
Supón que server.log contiene estos registros, con una línea en blanco antes del último:
2026-03-01 08:14 INFO Server started
2026-03-01 08:20 ERROR Disk almost full
2026-03-01 09:02 INFO User login: maya
2026-03-01 09:15 WARNING Slow response
2026-03-01 10:40 ERROR Database timeout
2026-03-01 11:05 INFO Backup finished
Cada registro no vacío tiene una fecha, una hora, un nivel y un mensaje. Divide solo tres veces para mantener unido el mensaje:
errors = 0
with open("server.log", encoding="utf-8") as f:
for line in f:
line = line.strip()
if not line:
continue
parts = line.split(maxsplit=3)
if parts[2] == "ERROR":
errors += 1
print(parts[3])
print(errors, "errors")
Para el segundo registro, parts[2] es "ERROR" y parts[3] es "Disk almost full". Se imprime ese mensaje y el contador sube a 1. El error posterior lo sube a 2. El programa imprime ambos mensajes y después «2 errors».
Busca en la parte adecuada
| Comprobación | Qué pregunta |
|---|---|
line.startswith("From:") | ¿Empieza la línea con este texto? |
"ERROR" in line | ¿Aparece este texto en alguna posición? |
line.find("ERROR") | ¿Dónde aparece por primera vez, o es el resultado -1? |
parts[2] == "ERROR" | ¿Es este campo concreto exactamente el nivel de error? |
Buscar en cualquier posición también encontraría «INFO No ERRORS today». Comprobar el campo de nivel responde con más precisión a la pregunta sobre el registro de actividad.
Después de strip(), una línea en blanco es ""; dividirla da []. Acceder a parts[2] lanzaría entonces IndexError. continue salta esa línea antes de cualquier acceso por índice. Un registro no vacío pero incompleto también necesita una comprobación de longitud cuando puedan aparecer registros así.
Cuenta categorías o escribe un archivo filtrado
Un diccionario guarda un conteo por nivel. Para cada registro, asigna level = parts[2] y después counts[level] = counts.get(level, 0) + 1. Para el registro de actividad anterior, los conteos son {'INFO': 3, 'ERROR': 2, 'WARNING': 1}. El valor predeterminado 0 inicia una categoría la primera vez que aparece.
Para guardar los registros coincidentes, abre un destino separado en la misma sentencia with y escribe una línea cuando coincida su nivel. Conserva la line original si el espaciado importa; si escribes texto limpio, vuelve a añadir su salto de línea. Nunca abras el propio origen con "w": se vaciaría antes de empezar a leer.
Observa los caracteres invisibles
print(repr(line)) hace visibles los espacios finales y los saltos de línea, por ejemplo 'Disk full \n'. strip() elimina ambos, mientras que rstrip("\n") conserva los espacios. La lectura normal de texto convierte los terminadores de línea reconocidos de Windows, Unix y los Mac antiguos en "\n". Una última línea sin terminador sigue sin tenerlo. Un nombre de archivo recogido mediante input("File name: ").strip() permite que el mismo bucle trabaje con distintos archivos de entrada.
Puntos clave
- Limpia, selecciona, procesa e informa en pasos separados.
- Salta las líneas en blanco antes de acceder por índice a los campos separados.
- Comprueba el campo adecuado cuando una búsqueda en toda la línea pueda encontrar más de lo deseado.
- Usa un diccionario para mantener un contador por categoría.
- Escribe la salida filtrada en otro archivo.
repr()revela espacios y caracteres de salto de línea ocultos en la impresión normal.
2Localiza archivos mediante rutas
Un nombre de archivo correcto es solo una parte de su ubicación. La carpeta desde la que se inicia un programa afecta a las rutas relativas y puede ser distinta de la que contiene el archivo de programa. Seguirás rutas por un árbol de carpetas, evitarás las secuencias de escape en las cadenas de Windows y construirás ubicaciones con pathlib. Estas habilidades ayudan a explicar los errores por archivos no encontrados y permiten que un mismo proyecto localice sus datos y prepare carpetas de salida en distintos equipos.
2.1 Dónde busca Python un archivo
Una ruta describe una ubicación en un árbol de carpetas. Puede comenzar en la raíz de ese árbol o en el directorio de trabajo actual del programa. Un archivo puede existir en el equipo y aun así no encontrarse en la ubicación que solicita tu programa.
Lee una ruta desde su punto de partida
| Tipo | Ejemplo | Punto de partida |
|---|---|---|
| Absoluta, macOS o Linux | /Users/maya/data/notes.txt | La raíz / |
| Absoluta, Windows | C:/Users/Maya/data/notes.txt | La raíz de la unidad C |
| Relativa | data/notes.txt | Directorio de trabajo actual |
Supón que una carpeta llamada project contiene una carpeta scripts y otra data. Ejecutas python scripts/report.py mientras trabajas en project. Abrir "data/notes.txt" busca dentro de project/data, aunque el archivo de programa esté en project/scripts.
Si, en cambio, inicias el mismo archivo de programa mientras trabajas dentro de project/scripts, esa ruta relativa apunta al interior de project/scripts/data. El archivo de programa no se ha movido; ha cambiado el punto de partida.
from pathlib import Path
print(Path.cwd())
Esto imprime el directorio de trabajo actual. os.getcwd() después de import os proporciona la misma información como cadena. Los editores y las herramientas de ejecución pueden elegir un directorio de trabajo, así que compruébalo cuando la ubicación no esté clara.
Muévete por las carpetas
En una ruta relativa, . significa la carpeta actual y .. su carpeta padre. Desde project/scripts, ../data/notes.txt sube a project y después baja a data. Añadir .. sin comprobar la carpeta de partida puede llevar a un programa a la ubicación equivocada.
Una ruta absoluta es útil para identificar una ubicación exacta, pero una ruta como C:/Users/Maya/Desktop/data.csv vincula el código compartido a las carpetas de una persona. Usa una ruta relativa con un punto de partida claro o construye la ruta desde la carpeta del propio archivo de programa cuando los datos deban estar allí.
Conserva intactas las barras invertidas de Windows
Windows suele mostrar barras invertidas entre carpetas. En una cadena normal de Python, una barra invertida inicia una secuencia de escape: \n se convierte en un salto de línea y \t en una tabulación. Por tanto, el literal "C:\new\table.txt" no contiene la ruta que querías.
Estas formas conservan la ruta deseada:
raw = r"C:\new\table.txt"
escaped = "C:\\new\\table.txt"
forward = "C:/new/table.txt"
Python en Windows acepta barras normales. Una cadena sin procesar impide que las barras invertidas se conviertan en secuencias de escape, pero no puede terminar en una sola barra invertida. Por ejemplo, r"C:\data\" tiene una sintaxis no válida.
Comprueba el nombre además de la carpeta
Busca diferencias de escritura y extensiones ocultas: un archivo mostrado como «notes.txt» puede llamarse realmente «notes.txt.txt». Las mayúsculas y minúsculas también importan. Linux suele distinguir Data.csv de data.csv; la configuración habitual de Windows y macOS no lo hace. Respetar las mayúsculas y minúsculas reales permite que un proyecto funcione en distintos sistemas.
Puntos clave
- Las rutas relativas parten del directorio de trabajo actual.
- El directorio de trabajo puede ser distinto de la carpeta del archivo de programa.
.permanece en la carpeta actual;..se mueve a su carpeta padre.- Usa cadenas sin procesar, barras invertidas duplicadas o barras normales para las rutas de Windows.
- Comprueba los nombres exactos, las extensiones y las mayúsculas y minúsculas cuando no se encuentre un archivo.
2.2 Construcción de rutas con pathlib
El módulo estándar pathlib da a cada ruta su propio objeto. Un Path permite unir nombres de carpetas, examinar un nombre de archivo y realizar tareas habituales con archivos sin construir manualmente cadenas con separadores.
Une y examina
from pathlib import Path
p = Path("reports") / "2026" / "sales.csv"
print(p.name)
print(p.stem)
print(p.suffix)
print(p.parent)
Los tres primeros resultados son «sales.csv», «sales» y «.csv». La carpeta padre es la ruta reports/2026, que se muestra con el separador del sistema. Aquí / une partes de una ruta; no divide números. La función anterior os.path.join() también une partes de rutas representadas como cadenas.
Un Path describe una ubicación incluso antes de que exista algo en ella. p.exists() comprueba si hay algo en esa ubicación. p.is_file() y p.is_dir() distinguen un archivo de un directorio. Una comprobación de existencia no puede garantizar una apertura posterior: el archivo puede desaparecer o el acceso puede cambiar entre ambas operaciones. Maneja los errores de apertura cuando el programa necesite recuperarse.
Lee o escribe un archivo pequeño
open() acepta un Path directamente. Para un archivo pequeño, estos métodos también gestionan la apertura y el cierre:
p = Path("greeting.txt")
p.write_text("Hello\n", encoding="utf-8")
text = p.read_text(encoding="utf-8")
text pasa a ser "Hello\n". write_text() sustituye el contenido existente, igual que abrir con "w"; no sirve para añadir al final. read_text() carga el archivo completo, así que usa un bucle sobre el archivo cuando necesites procesar uno grande línea a línea.
Parte de la carpeta del archivo de programa
Un archivo de datos suministrado junto a un archivo de programa debe localizarse a partir de este, independientemente del directorio de trabajo:
base = Path(__file__).resolve().parent
scores_path = base / "data" / "scores.txt"
with open(scores_path, encoding="utf-8") as f:
scores = f.readlines()
__file__ identifica el archivo de programa. resolve() convierte su ruta en absoluta y parent selecciona la carpeta que lo contiene. En una consola interactiva, __file__ no está definido, por lo que este patrón se usa en un archivo de programa.
Localiza archivos y prepara carpetas de salida
for p in sorted(Path("logs").glob("*.txt")):
text = p.read_text(encoding="utf-8")
print(p.name, len(text.splitlines()))
glob("*.txt") selecciona las rutas coincidentes en logs. iterdir() produce las entradas de la carpeta sin ese filtro de patrón. Ordenarlas hace que el orden sea predecible. splitlines() cuenta las líneas del texto sin tratar el terminador de línea final como una línea vacía adicional.
La escritura crea un archivo, pero no las carpetas padre que falten. Prepáralas primero:
folder = Path("output") / "daily"
folder.mkdir(parents=True, exist_ok=True)
(folder / "report.txt").write_text("Ready\n", encoding="utf-8")
parents=True crea las carpetas que falten por encima de daily. exist_ok=True acepta un directorio que ya exista. No convierte un archivo normal existente en una carpeta.
Puntos clave
Pathune partes con/y funciona directamente conopen().name,stem,suffixyparentpermiten acceder a distintas partes de una ruta.- Una comprobación de existencia no garantiza que una apertura posterior tenga éxito.
read_text()lee todo el texto;write_text()lo sustituye.- Construye la ruta desde
Path(__file__).resolve().parentpara datos relativos al archivo de programa. - Usa
glob()para encontrar coincidencias ymkdir()para crear las carpetas que falten.
3Lee y escribe archivos CSV
Los datos de una tabla necesitan más estructura que un conjunto de líneas. Un nombre puede contener una coma, un campo puede contener un salto de línea y una cantidad sigue llegando como texto. Usarás el módulo CSV para conservar esos límites, convertir valores para los cálculos y escribir resultados que otro programa pueda leer. Las columnas con nombre hacen más claro el procesamiento, mientras que las comprobaciones de las cabeceras y de la estructura de las filas ayudan a detectar datos incompletos.
3.1 Lectura de filas y campos CSV
Un archivo CSV almacena una tabla como texto. Sus registros son filas y sus campos son los valores de las columnas. Las comas suelen separar los campos, pero los campos entrecomillados pueden contener comas e incluso saltos de línea. Usa el módulo csv para mantener unidos esos valores.
Deja que el lector gestione las comillas
name,quiz1,quiz2
Ana,8,9
Ben,7,6
"Lopez, Maria",10,8
La primera fila es una cabecera que contiene los nombres de las columnas. La última fila de datos tiene tres campos, no cuatro: la coma dentro del nombre entrecomillado pertenece al nombre. Una comilla doble dentro de un campo entrecomillado se escribe dos veces. Dividir cada línea con split(",") ignoraría esas reglas y separaría el nombre en partes.
import csv
with open("grades.csv", newline="", encoding="utf-8") as f:
reader = csv.reader(f)
header = next(reader)
for row in reader:
average = (int(row[1]) + int(row[2])) / 2
print(row[0], average)
El lector devuelve listas de cadenas. next(reader) consume la cabecera una vez y deja que el bucle procese los datos. El programa imprime «Ana 8.5», «Ben 6.5» y «Lopez, Maria 9.0». En la primera fila de datos, convertir "8" y "9" permite obtener un total de 17; después, dividir entre 2 da 8,5.
Coordina el manejo del archivo y la lectura de la tabla
Abre los archivos CSV con newline="" para que el módulo csv gestione por sí mismo los terminadores de línea. Esto importa cuando un campo entrecomillado incluye un salto de línea. Un registro CSV puede abarcar varias líneas físicas del archivo, por lo que dividir línea a línea no sustituye a un lector CSV.
El comportamiento predeterminado del lector mantiene los valores como cadenas. Sin conversión, sumar row[1] + row[2] une "8" y "9" para formar "89". Si olvidas saltar la cabecera, se intenta convertir "quiz1" y se lanza ValueError.
Si el archivo puede estar vacío, next(reader, None) consume la cabecera si existe y devuelve None en caso contrario. Una línea CSV completamente en blanco se convierte en []. Salta esas filas con if not row: continue antes de acceder por índice. Una fila no vacía con pocos campos también necesita una comprobación de longitud; saltar solo las filas en blanco no protege row[2] frente a todos los registros incompletos.
Ajusta la lectura al formato del archivo
reader = csv.reader(f, delimiter=";", skipinitialspace=True)
Esto selecciona el punto y coma como separador y elimina los espacios inmediatamente posteriores. Elige el separador que use realmente el archivo; cambiarlo no convierte las comas decimales en puntos decimales. float("2,50") sigue lanzando ValueError.
Algunas exportaciones de hojas de cálculo empiezan con una marca de orden de bytes UTF-8. Leerlas con encoding="utf-8" puede dejar "\ufeff" al principio del primer campo y convertir la cabecera "name" en "\ufeffname". Para ese formato, encoding="utf-8-sig" elimina el marcador; también puede leer archivos UTF-8 sin él.
Puntos clave
- Un registro CSV puede contener comas o saltos de línea dentro de campos entrecomillados.
- Usa
csv.readerpara respetar el entrecomillado, en lugar de dividir simplemente por comas. - Abre los archivos CSV con
newline=""y la codificación correspondiente. - El lector predeterminado devuelve cadenas; salta la cabecera antes de convertir valores numéricos.
- Comprueba si las filas están vacías o incompletas antes de acceder a los campos.
- Selecciona el delimitador correcto y gestiona la marca de orden de bytes cuando exista.
3.2 Escritura de filas de una tabla como CSV
Un escritor CSV convierte los valores en campos correctamente separados y entrecomillados. Proporciónale filas como secuencias de valores y deja que gestione los signos de separación y las comillas. Así evitas una salida que parece correcta hasta que un nombre o mensaje contiene una coma.
Escribe una cabecera y los datos
import csv
with open("summary.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerow(["name", "average"])
writer.writerow(["Ana", 8.5])
writer.writerow(["Lopez, Maria", 9.0])
El archivo contiene las filas name,average, Ana,8.5 y "Lopez, Maria",9.0. El escritor convierte los números en texto. Entrecomilla el nombre que contiene una coma y duplica cualquier comilla doble dentro de un campo entrecomillado. None se convierte en un campo vacío, por lo que volver a leer el archivo no recupera None automáticamente.
writerow() recibe una fila. writerows() recibe una secuencia de filas, como [["Ana", 8.5], ["Ben", 6.5]]. En cambio, pasar "Ana" directamente a writerow() le proporciona tres caracteres y produce A,n,a. Usa ["Ana"] para una fila de un campo.
Deja que CSV controle los terminadores de línea
Usa newline="" al abrir la salida. El escritor predeterminado termina los registros con "\r\n". Permitir además la conversión de saltos de línea del modo texto puede añadir un retorno de carro adicional en Windows y producir líneas en blanco no deseadas en algunos lectores. El argumento newline evita esa segunda capa de conversión.
Transforma un archivo en otro
with open("grades.csv", newline="", encoding="utf-8") as src, open("summary.csv", "w", newline="", encoding="utf-8") as dst:
reader = csv.reader(src)
writer = csv.writer(dst)
next(reader)
writer.writerow(["name", "average"])
for row in reader:
average = (int(row[1]) + int(row[2])) / 2
writer.writerow([row[0], round(average, 2)])
Para las filas de calificaciones «Ana,8,9», «Ben,7,6» y "Lopez, Maria",10,8, las medias respectivas son 8,5; 6,5; 9,0. El lector elimina el entrecomillado CSV del valor del campo de entrada; el escritor vuelve a añadir las comillas necesarias en la salida. round() controla el valor numérico escrito, aunque no obliga a mostrar dos cifras decimales. Usa un formato como f"{average:.2f}" cuando quieras exactamente dos cifras.
Añade al final sin repetir la cabecera
Antes de abrir un archivo para añadir contenido al final, comprueba si necesita cabecera:
from pathlib import Path
p = Path("sales.csv")
needs_header = not p.exists() or p.stat().st_size == 0
with open(p, "a", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
if needs_header:
writer.writerow(["item", "quantity"])
writer.writerow(["coffee", 4])
Un archivo existente pero vacío también necesita cabecera. Escribirla en cada ejecución coloca nombres de columnas en medio de los datos. Este patrón supone que un solo programa actualiza el archivo; comprobar su existencia no lo reserva frente a cambios de otros programas.
Puntos clave
- Pasa una secuencia de campos a
writerow()y una secuencia de filas awriterows(). - El escritor convierte valores y gestiona el entrecomillado;
Nonese convierte en un campo vacío. - Usa
newline=""tanto para la salida como para la entrada CSV. - Añade una cabecera solo cuando el archivo sea nuevo o esté vacío.
3.3 Uso de nombres de columnas en código CSV
El código basado en posiciones, como row[2], depende del orden de las columnas. Un lector basado en diccionarios permite nombrar el valor que necesitas. Un diccionario relaciona claves con valores; aquí, la cabecera proporciona las claves y cada registro de datos proporciona sus valores.
Lee los campos por su nombre
import csv
with open("inventory.csv", newline="", encoding="utf-8") as f:
reader = csv.DictReader(f)
rows = list(reader)
Para la cabecera product,stock,price y la fila notebook,12,2.50, el primer diccionario es {'product': 'notebook', 'stock': '12', 'price': '2.50'}. reader.fieldnames proporciona los nombres de la cabecera. Esta se consume automáticamente; llamar a next(reader) saltaría el primer registro de datos.
Usa row["stock"] para seleccionar las existencias, aunque cambie el orden de las columnas. Conviértelo con int() para comparar cantidades. Los valores siguen siendo cadenas; los nombres de las columnas no proporcionan tipos numéricos al lector.
Filtra y calcula el total
Supón que la tabla contiene 12 cuadernos a un precio de 2,50; 3 bolígrafos a 1,20; 0 grapadoras a 7,95 y 25 carpetas a 0,80.
low = [r for r in rows if int(r["stock"]) < 5]
value = sum(int(r["stock"]) * float(r["price"]) for r in rows)
low contiene las filas de los bolígrafos y las grapadoras. El valor es 53,6 u.m.: los cuadernos aportan 30, los bolígrafos 3,6, las grapadoras 0 y las carpetas 20. El filtro usa las existencias, mientras que el total usa tanto las existencias como el precio.
Distingue las claves ausentes de los valores ausentes
Los nombres de la cabecera deben coincidir exactamente. Name y name son claves distintas. Un espacio después de una coma puede pasar a formar parte de una cabecera; skipinitialspace=True elimina los espacios inmediatamente posteriores a los separadores.
Una cabecera name,quiz1,quiz2 con los datos Ben,7 produce {'name': 'Ben', 'quiz1': '7', 'quiz2': None}. La clave existe, pero falta su valor. int(None) lanza TypeError. Un campo presente pero vacío es "", y convertirlo lanza ValueError. En cambio, una clave ausente de la cabecera provoca KeyError al consultarla.
Con los datos Cara,1,2,3, los campos adicionales se agrupan como None: ['3']; los campos con nombre siguen conteniendo "Cara", "1" y "2". Comprueba la estructura de una fila cuando la exactitud de los totales dependa de todos los campos.
Escribe las columnas seleccionadas
with open("reorder.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=["product", "stock"])
writer.writeheader()
for r in low:
writer.writerow({"product": r["product"], "stock": r["stock"]})
fieldnames establece el orden de salida, independientemente del orden del diccionario. Las claves ausentes del diccionario se convierten en campos vacíos. Las claves adicionales lanzan ValueError de forma predeterminada: pasar un diccionario de inventario que contenga price a este escritor de dos columnas falla. Construye el diccionario más pequeño como se muestra o elige extrasaction="ignore" cuando quieras descartar los campos adicionales.
Puntos clave
DictReaderconsume la cabecera y devuelve diccionarios con valores de tipo cadena.- Los nombres de la cabecera deben coincidir exactamente con las claves de consulta.
- Un campo ausente toma
Nonede forma predeterminada; un campo presente pero vacío es"". - Los campos adicionales se guardan bajo la clave
Nonede forma predeterminada. DictWriternecesitafieldnamespara establecer el orden de las columnas.- Las claves de salida ausentes se convierten en campos vacíos; las claves inesperadas lanzan
ValueErrorde forma predeterminada.
4Maneja errores con try y except
Los nombres de archivo pueden ser incorrectos, el acceso puede denegarse y una columna numérica puede contener una palabra. Una excepción marca el punto donde la ejecución normal no puede continuar. Leerás informes de error, capturarás los problemas esperados y separarás las tareas que se realizan si todo va bien de la liberación de recursos. Seguir los errores a través de las llamadas a funciones te ayudará después a situar la recuperación donde se pueda tomar una decisión útil, como volver a intentar una lectura o informar de una fila rechazada.
4.1 Comprensión de un informe de error
Una excepción es un objeto que señala un problema durante la ejecución. Lanzarla interrumpe la ejecución normal. Si ningún manejador se ocupa de ella, Python termina el programa con una traza de la excepción, un informe de las llamadas que llevaron al error.
Empieza por abajo
def average(values):
return sum(values) / len(values)
def report():
scores = []
print(average(scores))
report()
La traza termina con ZeroDivisionError: division by zero. Empieza ahí: el tipo identifica la clase de problema y el mensaje aporta detalles. La entrada inmediatamente superior apunta a la división en average(). Las entradas anteriores muestran la llamada desde report() y la llamada original a report(). La lista está vacía, por lo que su longitud es 0. La línea señalada como fallida es donde aparece el problema; la asignación anterior de la lista vacía explica cómo surgió.
Elige el tipo correspondiente
| Tipo | Causa típica |
|---|---|
ValueError | int("3.5"): una cadena con un valor no aceptable |
TypeError | len(5): una operación con una clase de objeto incorrecta |
ZeroDivisionError | Dividir entre cero |
IndexError | Leer una posición de lista que no existe |
KeyError | Consultar una clave de diccionario ausente |
NameError | Usar un nombre no definido |
AttributeError | Pedir a un objeto un atributo que no tiene |
int("abc") recibe un tipo de entrada permitido, una cadena, pero no puede interpretar ese valor como un número entero. En cambio, "5" + 3 mezcla tipos incompatibles para la suma. Una cadena que contiene dígitos sigue siendo una cadena.
Las operaciones con archivos tienen tipos más específicos: FileNotFoundError para una ruta que no existe, PermissionError para un acceso denegado y FileExistsError al crear con "x" un archivo que ya existe. Abrir un directorio como un archivo normal puede lanzar IsADirectoryError. Descodificar bytes con una codificación incompatible puede lanzar UnicodeDecodeError.
Comprende el árbol genealógico
Las clases de excepción forman una jerarquía. Un manejador de una clase base puede capturar sus clases derivadas:
OSErrores la clase base de errores habituales del sistema de archivos, incluidosFileNotFoundErroryPermissionError.LookupErrores la clase base deIndexErroryKeyError.ArithmeticErrores la clase base deZeroDivisionError.UnicodeDecodeErrorestá bajoValueError.
Estas ramas descienden de Exception, que desciende de BaseException. En cambio, KeyboardInterrupt y SystemExit descienden directamente de BaseException. Esa distinción permite que except Exception deje pasar la interrupción del usuario y la salida del programa.
Separa los problemas de sintaxis, ejecución y lógica
La ausencia de dos puntos o de un paréntesis de cierre puede impedir que Python analice un archivo de programa. El SyntaxError resultante ocurre antes de ejecutarlo, por lo que un try en ese mismo archivo no puede capturarlo. Una excepción de ejecución ocurre mientras se ejecuta código válido. Un error lógico produce una respuesta incorrecta sin lanzar necesariamente ninguna excepción, como dividir un total entre un conteo equivocado.
Puntos clave
- Lee primero el tipo de excepción y el mensaje al final de una traza.
- Usa las entradas de llamadas para seguir el valor que falla hasta su origen.
ValueErrorindica un valor no aceptable;TypeErrorindica un tipo inadecuado.- Un manejador de una excepción base también captura las clases de excepción derivadas.
- Los errores de sintaxis, de ejecución y lógicos se producen de formas distintas.
4.2 Captura de un problema donde se puede manejar
Una sentencia try ejecuta código que puede fallar y ofrece una ruta de recuperación a determinadas excepciones. El manejador debe corresponder al problema que el programa espera y al que sabe responder.
Sigue el flujo
while True:
try:
age = int(input("Age: "))
break
except ValueError:
print("Please enter a whole number, like 34.")
print("Next year you will be", age + 1)
Escribir «twenty» hace que int() lance ValueError. Python omite el resto del try, incluido break, y ejecuta el manejador correspondiente. Después, el bucle vuelve a preguntar. Escribir «34» permite que el try termine mediante break, por lo que el programa sale del bucle e imprime «Next year you will be 35».
Un manejador no reanuda la ejecución en la sentencia que falló. La ejecución continúa después de la sentencia try, salvo que el propio manejador cambie ese flujo. Si ningún manejador coincide, la excepción se propaga hacia fuera.
Maneja de forma distinta los fallos distintos
try:
result = int(a) / int(b)
except ValueError:
print("Both values must be whole numbers.")
except ZeroDivisionError:
print("The second value cannot be 0.")
Una conversión incorrecta y un divisor cero necesitan mensajes distintos. Si la respuesta debe ser idéntica, agrupa los tipos en una tupla: except (ValueError, ZeroDivisionError):. Los paréntesis funcionan en todas las versiones de Python 3. Python 3.14 también permite una lista sin paréntesis cuando no hay una parte as; la forma con tupla sigue siendo clara entre versiones.
Python comprueba las cláusulas de arriba abajo y ejecuta la primera coincidencia. Sitúa FileNotFoundError antes de su clase base OSError si un archivo ausente necesita una respuesta especial. Invertirlas hace que el manejador especial sea inalcanzable.
Usa el mensaje sin ocultar otros errores de programación
try:
quantity = int(text)
except ValueError as err:
print("Cannot read quantity:", err)
err es el objeto de excepción; imprimirlo muestra su mensaje. type(err).__name__ da el nombre de su clase. Python elimina la vinculación de err del manejador cuando este termina, así que copia su mensaje en otra variable dentro del bloque si lo necesitas después.
Mantén pequeño el try. Sitúa los cálculos posteriores fuera del manejador de conversión cuando sus fallos necesiten otro tratamiento. except Exception: puede ocultar errores de programación, como una variable no definida. Un except: sin tipo es aún más amplio: también captura KeyboardInterrupt y SystemExit.
Intenta la operación, no una imitación aproximada
Comprobar text.isdigit() no comprueba todo lo que acepta int(). "-5" y " 34" no pasan esa prueba, pero se convierten correctamente; "²" la pasa, pero no se convierte con int(). Intentar la conversión y capturar ValueError usa las reglas de la propia conversión.
Haz algo visible o deja constancia al manejar datos incorrectos. Un except ValueError: pass vacío puede dejar que el programa continúe con resultados ausentes y sin explicar qué salió mal.
Puntos clave
- Una excepción omite el código restante de
tryy ejecuta el primer manejador coincidente. - Usa tipos específicos y sitúa los manejadores de clases derivadas antes que los de clases base.
- Agrupa los tipos en una tupla cuando su acción de recuperación sea la misma.
except ... as errda acceso al mensaje dentro del manejador.- Limita el
trya lo necesario para que los mensajes describan la operación que realmente falla. - Intenta directamente la conversión numérica cuando necesites comprobar qué acepta.
4.3 Éxito, liberación de recursos y errores entre funciones
Una sentencia try puede separar la operación que puede fallar, la recuperación, las tareas que se realizan si todo va bien y la liberación de recursos. Una excepción también puede salir de una función y ser manejada por el código que la llamó.
Da un bloque propio a las tareas que se realizan si todo va bien
try:
x = 10 / int(text)
except ValueError:
print("not a number")
except ZeroDivisionError:
print("zero")
else:
print("result", x)
finally:
print("done")
Con text = "4", el programa imprime «result 2.5» y «done». Con "abc", imprime «not a number» y «done»; con "0", imprime «zero» y «done».
else se ejecuta cuando el try termina normalmente sin una excepción. No se ejecuta después de que un manejador se recupere de un error. También se omite cuando return, break o continue sale antes de tiempo del try. Los errores lanzados dentro de else no son capturados por las cláusulas except anteriores de esa sentencia, por lo que las tareas de éxito no comparten por accidente los manejadores de la operación que puede fallar.
Libera recursos en todas las rutas de salida
finally se ejecuta cuando el control sale de la sentencia: después de que todo vaya bien, tras una excepción manejada y antes de que una excepción no manejada siga propagándose. También se ejecuta antes de completar un retorno pendiente.
def label():
try:
return "from try"
finally:
print("finally ran")
value = label()
print(value)
Esto imprime «finally ran» y después «from try». El retorno esperaba mientras se liberaban los recursos. Para los archivos, with ya proporciona el cierre, por lo que normalmente elimina la necesidad de cerrarlos manualmente en finally.
No incluyas una salida como return, break o continue en finally. Salir así del bloque de liberación de recursos puede descartar una excepción pendiente o sustituir un retorno. Python 3.14 y posteriores emiten un SyntaxWarning para este patrón. Limita ese bloque a liberar recursos.
Sigue una excepción hasta el código que realizó la llamada
def read_scores(path):
with open(path, encoding="utf-8") as f:
return [int(line) for line in f]
try:
scores = read_scores("scores.txt")
except FileNotFoundError:
print("The score file is missing.")
Si la apertura falla, read_scores() no tiene manejador, por lo que FileNotFoundError se propaga hasta la llamada dentro del try externo. El código que realizó la llamada la maneja e imprime el mensaje. Si una línea no es un número entero, un ValueError sigue la misma ruta, pero el manejador de archivos ausentes no coincide con él.
Elige el nivel que pueda dar una respuesta útil
Una función de lectura puede saber cómo obtener datos, pero no si un archivo ausente debe provocar otro intento, la omisión de una tarea o una detención controlada. Dejar que la excepción llegue al código que realiza la llamada e interactúa con el usuario deja allí esa decisión. Capturarla demasiado pronto y devolver una lista vacía puede ocultar la diferencia entre un archivo vacío y una lectura fallida.
Puntos clave
elsesolo se ejecuta después de que el cuerpo detrytermine normalmente.finallyse ejecuta antes de que salga el control, incluso en un retorno o ante una excepción no manejada.- Una excepción en
elsequeda fuera de los manejadores anteriores de esa sentencia. - Evita salidas de
finallyque puedan descartar errores o retornos pendientes. - Las excepciones no manejadas se propagan a través de las llamadas hasta un manejador externo coincidente.
4.4 Recuperación de errores en archivos y filas
Un programa gestiona un fallo de forma controlada cuando responde a un problema de manera controlada y útil. Puede volver a preguntar, informar de una fila omitida o detenerse con un mensaje claro. Elige esa respuesta según el uso que se vaya a dar al resultado.
Vuelve a intentarlo si el archivo no existe
while True:
name = input("File name: ").strip()
try:
with open(name, encoding="utf-8") as f:
text = f.read()
except FileNotFoundError:
print(f"No file named '{name}'. Please try again.")
else:
break
print(len(text.splitlines()), "lines")
Una apertura fallida omite la asignación y llega al manejador. El bucle vuelve a preguntar. Una lectura correcta llega a else, termina el bucle y deja text disponible para el conteo final. with cierra el archivo en cualquiera de las salidas de un bloque en el que se haya entrado.
Para distintos problemas con archivos, usa FileNotFoundError, después PermissionError y luego un manejador general de OSError si otros errores del sistema de archivos necesitan respuesta. Las cláusulas específicas deben ir primero. Descodificar bytes incorrectos es otro problema; un mensaje sobre una ruta ausente no lo describiría.
Maneja cada fila de datos por separado
Para un resumen rápido de ventas, supón que las filas CSV después de la cabecera son coffee,4, tea,two, muffin,3, cookie, y juice,5.
import csv
total = 0
skipped = 0
with open("sales.csv", newline="", encoding="utf-8") as f:
reader = csv.reader(f)
next(reader, None)
for row in reader:
try:
if len(row) != 2:
raise ValueError("expected two fields")
quantity = int(row[1])
except ValueError as err:
skipped += 1
print(f"sales.csv, ending line {reader.line_num}: {err}")
else:
total += quantity
print("Total:", total, "Skipped:", skipped)
Las cantidades válidas suman 12. Se rechazan la palabra «two» y la cantidad vacía, por lo que el conteo de filas omitidas es 2. La comprobación de la fila también convierte un número inesperado de campos en un error de datos comunicado antes de acceder por índice. Situar try dentro del bucle permite procesar el siguiente registro después de que uno falle; situar el bucle dentro de un único try haría que se saliera del bucle en el primer fallo.
Indica las ubicaciones con precisión
Para los cinco registros de una sola línea, los valores incorrectos terminan en las líneas 3 y 5 del archivo. Aquí enumerate(reader, start=2) coincidiría con esos números de línea, pero un salto de línea entrecomillado hace que un registro CSV abarque más de una línea. reader.line_num indica cuántas líneas físicas ha consumido el lector. Llamarla línea final mantiene la precisión de los mensajes para registros de varias líneas.
Decide si un resultado parcial es aceptable
Un conteo exploratorio rápido puede permitir omisiones comunicadas. Un total financiero o de calificaciones puede necesitar todos los registros: detente y pide datos corregidos en lugar de presentar un total parcial como completo. Indica el archivo, la ubicación y el problema para que pueda corregirse.
Después de import sys, sys.exit("Could not open sales.csv") escribe el mensaje en la salida de errores y termina con el código de salida 1. Lanza SystemExit, que except Exception no captura. Mantén los manejadores específicos para que un error de programación ajeno no se identifique erróneamente como un problema de archivo.
Puntos clave
- Elige volver a intentar, saltar o detener según la tarea.
- Sitúa la recuperación por fila dentro del bucle para continuar después de una fila incorrecta.
- Informa de los registros omitidos e identifica claramente los resultados parciales.
- Los números de registro CSV pueden diferir de los números de línea física.
sys.exit(message)termina con un mensaje de error y el código de salida 1.- Usa manejadores específicos para que el mensaje corresponda al problema real.
5Lanza tus propias excepciones
Las funciones necesitan una forma clara de informar de datos de entrada que no pueden manejar. Lanzar una excepción impide que una operación fallida produzca un resultado engañoso y permite que el código que realizó la llamada elija una respuesta. Elegirás tipos y mensajes con sentido, propagarás un error existente y conservarás su causa al convertirlo en otro. Un patrón breve de clase personalizada da al programa su propio tipo de error cuando el código que realiza las llamadas necesita distinguir un problema de otro.
5.1 Rechazo de datos de entrada con raise
Una función debe avisar cuando no pueda producir un resultado válido. raise inicia una excepción en ese punto para que la ruta no válida no continúe como si la operación hubiera tenido éxito.
Comprueba antes de calcular
def withdraw(balance, amount):
if amount <= 0:
raise ValueError(f"amount must be positive, got {amount}")
if amount > balance:
raise ValueError(f"amount {amount} is more than the balance {balance}")
return balance - amount
withdraw(100, 30) devuelve 70. withdraw(100, 150) lanza un error sobre el saldo; withdraw(100, -5) lanza un error sobre un importe no positivo. Ninguna de las llamadas que fallan llega a la resta.
Una excepción lanzada sigue las mismas reglas de manejo que un error incorporado. Si un manejador coincidente dentro de la función la captura, la ejecución puede continuar allí. En caso contrario, la excepción sale de la función y llega al código que la llamó. Si no se encuentra ningún manejador, Python muestra una traza de la excepción.
Deja que el código que realiza la llamada elija la respuesta
balance = 100
amount = 150
try:
balance = withdraw(balance, amount)
except ValueError as err:
print(f"Cannot withdraw: {err}")
La función informa de por qué no puede retirar el importe. El código que realiza la llamada decide mostrar un mensaje. Como la llamada a la función falla antes de devolver un valor, la asignación no sustituye el saldo anterior por un resultado. Otro código que la llamara podría pedir un importe menor o cancelar una transacción sin modificar la función.
En cambio, imprimir una advertencia dentro de la función y devolver None puede permitir que el código que la llama lleve un valor no válido a un cálculo posterior. Lanzar una excepción mantiene el fallo unido a su causa y proporciona al código que realiza la llamada una ruta de error diferenciada.
Elige un tipo con sentido
| Problema | Tipo adecuado |
|---|---|
| Clase de entrada correcta, valor no aceptable | ValueError |
| Clase de objeto incorrecta para la operación | TypeError |
Un importe numérico negativo tiene un valor no aceptable. Una lista proporcionada donde se necesita un número tiene un tipo inadecuado. El tipo de excepción forma parte del comportamiento de la función: el código que la llama lo usa para seleccionar manejadores. No elijas un tipo solo porque te resulte familiar.
Escribe un mensaje útil
Un mensaje debe indicar qué se esperaba y qué se recibió. f"age must be between 0 and 130, got {age}" orienta hacia una corrección. Un mensaje como «error» no aporta detalles útiles. Centra el mensaje en la operación fallida; el código que interactúa con el usuario puede añadir el contexto general.
raise ValueError("amount must be positive") crea una excepción con un mensaje. raise ValueError también es válido y crea una sin mensaje. Una cadena simple no es una excepción: raise "error" lanza TypeError porque los objetos lanzados deben derivar de BaseException.
Puntos clave
- Lanza una excepción en el punto donde una función no pueda continuar correctamente.
- Usa
ValueErrorpara un valor no aceptable yTypeErrorpara un tipo inadecuado. - Incluye la entrada esperada y el valor recibido en un mensaje útil.
- Deja que el código que realiza la llamada decida cómo responder a la operación fallida.
5.2 Propagación y denominación de excepciones
A veces una función detecta un error, pero no puede terminar de manejarlo. Puede necesitar propagar el mismo error, convertirlo en otro más útil o dar a un problema concreto del programa su propio tipo de excepción.
Vuelve a lanzar el error actual
def read_text(path):
try:
with open(path, encoding="utf-8") as f:
return f.read()
except FileNotFoundError:
print(f"Missing: {path}")
raise
El raise sin argumentos dentro del manejador vuelve a lanzar la excepción actual. Imprimir solo un mensaje terminaría el manejador y haría que la función devolviera None; relanzarla hace visible la lectura fallida al código que realizó la llamada. Un raise sin argumentos necesita una excepción activa que volver a lanzar.
Convierte la excepción conservando la causa
def read_price(row):
try:
text = row["price"]
except KeyError as err:
raise ValueError("row has no 'price' column") from err
return float(text)
Una clave ausente se convierte en un ValueError con un mensaje sobre la fila. from err registra el KeyError original como su causa directa. La traza muestra el error original, el vínculo entre ambos y el nuevo error. El código que realiza la llamada puede manejar el tipo resultante mientras la depuración conserva la causa de nivel inferior.
Este manejador se limita a la consulta por clave. Un valor presente como "free" falla después en float(text) con su propio ValueError; no se informa falsamente de que falta una columna.
Define un tipo distinto
class InsufficientFundsError(ValueError):
pass
Este patrón crea una clase de excepción personalizada. Por convención, el nombre termina en Error. El nombre entre paréntesis es su clase base, por lo que esta clase es un tipo de ValueError.
def withdraw(balance, amount):
if amount > balance:
raise InsufficientFundsError(
f"balance {balance}, requested {amount}"
)
return balance - amount
try:
withdraw(100, 150)
except InsufficientFundsError as err:
print("Not enough money:", err)
El programa imprime «Not enough money: balance 100, requested 150». El código que realiza la llamada puede distinguir la falta de fondos de otro valor no válido. Si apareciera un manejador de ValueError antes de este manejador específico, el de la clase base lo capturaría primero.
Elige la clase base según el manejo deseado
Derivar de ValueError permite que tanto un manejador específico como otro más amplio de errores de valor capturen el tipo personalizado. Derivar directamente de Exception crea una rama separada de errores ordinarios, por lo que except ValueError no lo capturaría. Un tipo personalizado es útil cuando el código que realiza las llamadas necesita una respuesta distinta; un tipo incorporado y un mensaje claros bastan cuando no la necesita.
Puntos clave
- Un
raisesin argumentos en un manejador propaga la excepción actual. raise NewError(...) from errregistra el error original como causa directa.- Una excepción personalizada proporciona al código que realiza la llamada un tipo de problema distinto.
- La clase base determina qué manejadores más amplios pueden capturar el error personalizado.
- Sitúa un manejador personalizado específico antes del manejador de su clase base.
Ejemplos de Archivos y excepciones en Python
1Convierte un archivo de texto en un informe filtrado
13 pasos
- 1IntroducciónLee, decide y guarda
Un registro de soporte contiene un evento por línea. Quieres un archivo nuevo que contenga solo los eventos que necesitan atención. Esa tarea combina lectura, comprobaciones de cadenas y escritura.
Primero observa cómo proporciona texto un archivo. Después construye el filtro en pasos pequeños, manteniendo la entrada separada de la salida y dejando que
withcierre ambos archivos cuando termine el procesamiento. - 2ExplicaciónUn archivo proporciona cadenas
Supón que
events.txtcontiene"INFO Ready\nERROR Queue full\n". Abrirlo crea un objeto de archivo, no una copia de su texto.f.readline()devuelve"INFO Ready\n". Una segunda llamada devuelve"ERROR Queue full\n". Una tercera devuelve""porque el archivo se ha agotado. El salto de línea permanece unido a la línea devuelta; el texto numérico también seguiría siendo texto hasta convertirlo explícitamente. - 3DesafíoElige un método de lectura
Un registro de actividad puede ser mucho mayor que la memoria disponible. Solo necesitas examinar cada línea una vez. ¿Cómo deberías leerlo y por qué?
---reveal---
Recorre directamente el archivo abierto con
for line in f:. Proporciona una línea cada vez sin necesitar primero una cadena o lista del archivo completo. Llamar aread()oreadlines()cargaría en memoria el contenido restante. - 4EjemploMantén la lectura dentro del bloque
with open("events.txt", encoding="utf-8") as f: first = f.readline() print(first.rstrip("\n"))La lectura ocurre mientras el archivo está abierto. Salir del bloque con sangría lo cierra; la impresión posterior usa la cadena guardada. Por eso una operación sobre
firstpuede realizarse después, mientras que otrof.readline()no. - 5DesafíoPredice la liberación de recursos tras un error
Dentro de ese bloque de archivo, supón que
int("oops")lanzaValueError. El código que lo rodea no tiene manejador. ¿Permanece abierto el archivo? ¿Ocultawithel error?---reveal---
El archivo se cierra cuando la ejecución sale del bloque en el que había entrado. El error sigue propagándose y produce una traza de excepción si nada lo captura. La liberación automática de recursos controla cuánto tiempo permanece abierto el archivo; se necesitaría un manejador
exceptpara recuperarse. - 6ExplicaciónElige el comportamiento de la salida
El informe filtrado debe sustituir a uno anterior, así que abre una ruta de salida distinta con
"w". Ese modo vacía inmediatamente un archivo existente.Para un historial de actividad que conserve ejecuciones anteriores, usa
"a". Si hay que proteger un informe existente frente a la sustitución, usa"x"y manejaFileExistsError. La creación de archivos sigue necesitando que existan las carpetas que los contienen. - 7EjemploEscribe exactamente una línea
Para escribir una línea seleccionada, conserva su terminador original:
dst.write(line)Si la has limpiado con
strip(), vuelve a añadir el terminador:dst.write(cleaned + "\n")write()no añade separadores.print(cleaned, file=dst)es otra forma de añadir un salto de línea, mientras quewritelines()sigue esperando que las cadenas proporcionadas contengan los terminadores necesarios. - 8DesafíoPredice dos ejecuciones
Al principio no existe el archivo y un programa se ejecuta dos veces. Cada ejecución abre
"runs.txt"en modo de adición al final y llama af.write("OK"). ¿Qué texto se guarda?---reveal---
El archivo contiene
"OKOK". El modo de adición al final conserva la primera ejecución, pero ni el modo niwrite()añaden un salto de línea. Escribir"OK\n"produciría una línea por ejecución. Abrir con"w"dejaría solo el último"OK". - 9EjemploLimpia antes de seleccionar
Nuestro registro de actividad usa la primera palabra como nivel. Empieza cada iteración con:
cleaned = line.strip() if not cleaned: continue level = cleaned.split(maxsplit=1)[0]La comprobación de línea vacía evita acceder por índice a una lista vacía. Conservar por separado la
lineoriginal permite que la salida mantenga su espaciado. Solo se usa la copia limpia para identificar el nivel. - 10DesafíoComprueba la parte adecuada
El registro incluye «INFO ERROR counter reset» y «ERROR Queue full». ¿Qué comprobación de nivel guarda solo el segundo registro?
---reveal---
Comprueba
level == "ERROR"después de extraer la primera palabra. Buscar"ERROR"en cualquier posición también guardaría el registro informativo porque la palabra aparece en su mensaje. El formato indica dónde encontrar la categoría que estás seleccionando. - 11EjemploMonta el filtro
count = 0 with open("events.txt", encoding="utf-8") as src, open("urgent.txt", "w", encoding="utf-8") as dst: for line in src: cleaned = line.strip() if not cleaned: continue if cleaned.split(maxsplit=1)[0] == "ERROR": dst.write(line) count += 1 print(count, "saved")El contador cambia solo cuando se escribe un registro. Ambos archivos se cierran antes de imprimir el conteo.
- 12DesafíoDiagnostica la pérdida del origen
Alguien cambia el nombre de salida a
"events.txt"y mantiene"w". ¿Por qué el filtro corre ahora el riesgo de no guardar nada, aunque el origen se haya abierto primero?---reveal---
La segunda apertura vacía el mismo archivo subyacente antes de que el bucle lo lea. El primer objeto de archivo no ha guardado una copia separada del texto anterior. Vuelve a usar una ruta de salida distinta para que la transformación no pueda borrar su entrada al abrir.
- 13RepasoSigue una tarea con archivos antes de ejecutarla
Para una transformación de archivos, sigue cuatro decisiones: de dónde viene la entrada, cuánto texto se lee a la vez, qué selecciona un registro y qué hace la apertura de la salida con los datos existentes.
Después comprueba los límites de los bloques. Las operaciones con archivos necesitan manejadores abiertos; las cadenas, listas y totales guardados pueden usarse después de cerrarlos.
2Localiza los datos del proyecto desde cualquier carpeta de inicio
9 pasos
Guarda esta unidad para seguir cada Lección Interactiva paso a paso.
- 1IntroducciónLocaliza la carpeta de partida
- 2EjemploSigue un inicio de ejecución
- 3DesafíoCambia la carpeta de inicio
- 4ConsejoExamina antes de cambiar la ruta
- 5EjemploConstruye desde el archivo de programa
- 6ExplicaciónPrepara un destino
- 7DesafíoExamina un nombre y busca coincidencias
- 8DesafíoComprueba una solución propuesta
- 9RepasoSepara ubicación y disponibilidad
3Lee una tabla y escribe un informe con columnas por nombre
13 pasos
Guarda esta unidad para seguir cada Lección Interactiva paso a paso.
- 1IntroducciónConserva la estructura de la tabla
- 2EjemploLee un registro entrecomillado
- 3EjemploAbre y convierte
- 4DesafíoReconoce una fila incompleta
- 5EjemploEscribe valores como campos
- 6DesafíoMantén unido un campo
- 7ExplicaciónUsa la cabecera como claves
- 8EjemploFiltra por existencias
- 9DesafíoDistingue lo ausente de lo vacío
- 10EjemploExporta las columnas seleccionadas
- 11DesafíoAñade un lote posterior
- 12ConsejoAjusta los separadores y las codificaciones
- 13RepasoComprueba la estructura y el significado
4Sigue un error desde una fila incorrecta hasta una respuesta útil
15 pasos
Guarda esta unidad para seguir cada Lección Interactiva paso a paso.
- 1IntroducciónElige de qué fallos se puede recuperar el programa
- 2EjemploEmpieza por el tipo de excepción
- 3DesafíoReconoce un fallo distinto
- 4EjemploCaptura solo el error de conversión esperado
- 5DesafíoOrdena los manejadores relacionados
- 6ExplicaciónDa tareas distintas al éxito y a la liberación de recursos
- 7DesafíoSigue un error sin manejador coincidente
- 8ConexiónDeja decidir al código que realiza la llamada
- 9EjemploMantén la recuperación dentro del bucle de registros
- 10EjemploSigue tres registros
- 11DesafíoCambia el límite del bucle
- 12ConsejoIndica la ubicación correctamente
- 13DesafíoElige un resultado completo
- 14EjemploTermina con un código de error
- 15RepasoSitúa cada respuesta en el nivel adecuado
5Diseña el comportamiento de una función ante errores
10 pasos
Guarda esta unidad para seguir cada Lección Interactiva paso a paso.
- 1IntroducciónDa al fallo una ruta clara
- 2EjemploRechaza solicitudes no válidas
- 3DesafíoSigue una asignación fallida
- 4ExplicaciónAjusta el tipo al problema
- 5EjemploDa un nombre propio a la falta de plazas
- 6DesafíoMantén accesible la respuesta específica
- 7EjemploReacciona y propaga el error
- 8EjemploConvierte un fallo de nivel inferior
- 9DesafíoElige la relación adecuada
- 10RepasoMantén el error útil para el código que realiza la llamada
Ejercicios de Archivos y excepciones en Python
Set 1: Elección de métodos y manejo de fallos esperados10 Preguntas de Práctica
Pregunta 1 de 10
"09:10 INFO ERROR count reset" y "09:12 ERROR Network down". El nivel es el segundo campo separado por espacios en blanco. ¿Qué condición selecciona solo los registros de nivel de error?Mostrar respuestaOcultar respuesta
Pregunta 2 de 10
"12\n15\n". ¿Qué pareja resulta de first = f.read() seguido de second = f.read() sobre un mismo lector recién abierto?Mostrar respuestaOcultar respuesta
read() consume todo el texto restante, incluido el salto de línea final. El segundo empieza al final y devuelve una cadena vacía. Leer no reinicia la posición ni convierte los dígitos en números enteros, por lo que no se obtiene otra lectura completa ni una lista numérica.Pregunta 3 de 10
"C:\new\tasks.txt" no identificar el archivo deseado?Mostrar respuestaOcultar respuesta
\n se convierte en un salto de línea y \t en una tabulación, lo que cambia el texto de la ruta almacenado. Usa una cadena sin procesar, barras invertidas duplicadas o barras normales para conservar los caracteres deseados. Una ruta que incluye una unidad no se vuelve relativa por usar barras invertidas.Pregunta 4 de 10
city,visitors y Mesa,24. Después de reader = csv.DictReader(f), el programa llama una vez a next(reader) y después recorre el lector con un bucle. ¿Por qué no aparece Mesa en ese bucle?Mostrar respuestaOcultar respuesta
DictReader ya usa la cabecera como claves, por lo que el primer elemento que devuelve es el diccionario de datos de Mesa. Llamar a next(reader) consume ese elemento antes de que empiece el bucle. Un csv.reader normal necesita saltar la cabecera por separado; copiar aquí ese paso hace que se pierdan datos.Pregunta 5 de 10
label;count, pero el lector CSV predeterminado devuelve ["label;count"]. ¿Qué ajuste del lector corresponde a este archivo?Mostrar respuestaOcultar respuesta
delimiter=";" hace que el lector reconozca dos campos. Eliminar los espacios después de los separadores no cambia qué separador se reconoce. Los ajustes de entrecomillado tampoco hacen que el punto y coma actúe como la coma delimitadora predeterminada.Pregunta 6 de 10
¿Qué se imprime?
try:
value = 18 / int("0")
except ZeroDivisionError:
print("zero")
else:
print("success")
finally:
print("closed")
Mostrar respuestaOcultar respuesta
"0" tiene éxito, pero la división lanza ZeroDivisionError. Su manejador imprime «zero», se omite else y finally imprime «closed». Manejar el error no convierte la ejecución original de try en una finalización normal a efectos de else.Pregunta 7 de 10
Mostrar respuestaOcultar respuesta
Pregunta 8 de 10
FileNotFoundError en un try. El primer manejador es except OSError: print("file problem") y el segundo es except FileNotFoundError: print("missing"). ¿Qué se imprime?Mostrar respuestaOcultar respuesta
FileNotFoundError deriva de OSError, por lo que el primer manejador ya coincide e imprime «file problem». Python ejecuta solo la primera cláusula coincidente. Sitúa primero el manejador específico cuando un archivo ausente necesite una respuesta distinta de la de otros errores del sistema de archivos.Pregunta 9 de 10
except ValueError:, ¿qué sentencia propaga la misma excepción activa al código que realizó la llamada?Mostrar respuestaOcultar respuesta
raise sin argumentos vuelve a lanzar la excepción activa y mantiene visible la operación fallida fuera del manejador actual. pass simplemente no hace nada y permite que ese manejador termine normalmente. Un retorno saldría de la función normalmente en lugar de propagar el error original.Pregunta 10 de 10
¿Qué se imprime?
def reserve(n):
if n <= 0:
raise ValueError("positive count required")
return n * 2
result = 7
try:
result = reserve(0)
except ValueError:
print(result)
Mostrar respuestaOcultar respuesta
reserve(0) lanza una excepción antes de devolver un valor, por lo que la asignación a result no se completa. El valor anterior, 7, permanece y el manejador lo imprime. Una excepción no hace que una llamada fallida devuelva None; interrumpe la expresión.Set 2: Lectura de archivos y seguimiento de programas pequeños10 Preguntas de Práctica
Guarda esta unidad para ver todas las respuestas y practicar cada set.
Pregunta 1 de 10
writer.writerow("Leo") con la coma como delimitador predeterminado?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 2 de 10
"oak\npine". Justo después de abrirlo para leer, ¿qué devuelve f.readline()?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 3 de 10
El bloque termina normalmente. ¿Qué se imprime?
with open("memo.txt", encoding="utf-8") as f:
text = f.read()
print(f.closed)
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 4 de 10
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 5 de 10
/work/lab. Ejecuta python tools/count.py, que abre "inputs/list.txt". ¿Qué ubicación absoluta solicita esa ruta relativa?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 6 de 10
p = Path("exports/week/report.csv"), ¿cuál es el valor de p.stem?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 7 de 10
csv.reader predeterminado, ¿qué lista se lee del registro "River, West",6,8?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 8 de 10
"many". ¿Qué excepción lanza int(row["quantity"])?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 9 de 10
¿Qué se imprime?
def read_count(text):
return 12 / int(text)
try:
result = read_count("0")
print("read")
except ValueError:
print("bad text")
except ZeroDivisionError:
print("zero")
print("end")
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 10 de 10
-2, ¿qué excepción y mensaje son adecuados?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Set 3: Procesamiento de archivos y rutas de recuperación10 Preguntas de Práctica
Guarda esta unidad para ver todas las respuestas y practicar cada set.
Pregunta 1 de 10
{"east": 4}["west"]?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 2 de 10
Un archivo contiene solo «bad». ¿Qué se imprime?
try:
with open("one.txt", encoding="utf-8") as f:
value = int(f.readline())
except ValueError:
print(f.closed)
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 3 de 10
f.writelines(["red", "blue\n"]) y después se abre otra vez en modo de adición al final para escribir "green\n". ¿Qué texto contiene?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 4 de 10
results y results/daily no existen. ¿Qué debe ejecutarse antes de escribir con Path("results/daily/run.txt").write_text("ok", encoding="utf-8")?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 5 de 10
not p.exists(). La ruta existe, pero tiene cero bytes. ¿Qué condición proporciona también a este archivo la cabecera que necesita?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 6 de 10
DictReader predeterminado tiene la cabecera name,first,second y lee Inez,5. ¿Qué valor se almacena bajo "second" y qué ocurre al pasarlo a int()?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 7 de 10
¿Qué recibe el código que realiza la llamada y qué se imprime primero?
def choose():
try:
return 11
finally:
print("leaving")
x = choose()
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 8 de 10
try/except ValueError de la conversión?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 9 de 10
class LimitError(ValueError): pass, se lanza un LimitError. ¿Qué ocurre si except ValueError: aparece antes de except LimitError:?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 10 de 10
parts = line.split(maxsplit=2). Los registros deben tener fecha, nivel y mensaje, pero algunos solo contienen una fecha. ¿Qué comprobación debe preceder a parts[1] y parts[2]?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Set 4: Diagnóstico de datos incompletos y manejadores engañosos10 Preguntas de Práctica
Guarda esta unidad para ver todas las respuestas y practicar cada set.
Pregunta 1 de 10
f.readline()?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 2 de 10
data.txt contiene tres registros. Un programa lo abre con "r", después abre la misma ruta con "w" y solo entonces empieza a leer mediante el primer manejador. ¿Por qué existe el riesgo de perder la entrada?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 3 de 10
p.exists() devuelve True, pero el archivo se elimina antes de open(p, encoding="utf-8"). ¿Qué sigue necesitando un programa robusto en esa apertura?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 4 de 10
data/menu.txt junto a su propia ubicación, independientemente de la carpeta de inicio. ¿Qué expresión construye esa ruta en el archivo de programa?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 5 de 10
encoding="utf-8", su primera clave de cabecera es "\ufeffcode". ¿Qué cambio en la apertura elimina el marcador y conserva el texto UTF-8?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 6 de 10
{"title": "Map", "stock": "4", "cost": "3.50"}. Un DictWriter predeterminado tiene fieldnames=["title", "stock"]. ¿Qué ocurre cuando escribe la fila completa sin cambios?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 7 de 10
ValueError de int(text). Ese manejador imprime missing_name, que nunca se ha definido. ¿Qué ocurre con el nuevo NameError?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 8 de 10
"North en la línea física 2 y termina con Hall",7 en la línea 3. Después de leerlo, ¿qué ubicación indica reader.line_num?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 9 de 10
None para un tamaño negativo. El código que la llama multiplica inmediatamente el resultado por 4. ¿Por qué mejoraría esta ruta de fallo lanzar ValueError durante la validación?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 10 de 10
KeyError como err, un manejador ejecuta raise ValueError("missing unit column") from err. ¿Qué recibe el código que realiza la llamada y qué causa se conserva?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Set 5: Combinación del procesamiento de archivos con un manejo fiable de errores10 Preguntas de Práctica
Guarda esta unidad para ver todas las respuestas y practicar cada set.
Pregunta 1 de 10
with open("source.txt", encoding="utf-8") as src, open("new.txt", "x", encoding="utf-8") as dst:. El origen se abre, pero new.txt existe. ¿Qué ocurre con src y el cuerpo?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 2 de 10
"10:00 INFO ERROR resolved", "10:01 ERROR Disk slow" y "10:02 ERROR Disk full". El segundo campo es el nivel. Después de filtrar por nivel de error, ¿cuántos registros se guardan?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 3 de 10
/srv/course, ejecuta tools/read.py y abre "../shared/items.txt". ¿Qué ruta solicita?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 4 de 10
["Vale, East", None, 3]. ¿Qué registro se produce, sin contar su terminador de línea final?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 5 de 10
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 6 de 10
¿Qué se imprime antes de que se propague el error?
try:
n = int("2")
except ValueError:
print("bad input")
else:
print("ready")
result = 9 / 0
finally:
print("cleanup")
Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 7 de 10
int(), incluidos espacios iniciales y un signo. ¿Por qué intentar int(text) en try en lugar de exigir primero text.isdigit()?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 8 de 10
sys.exit("Required file unavailable") dentro de código cubierto por except Exception:. ¿Qué ocurre?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 9 de 10
total = 0 y skipped = 0. Un manejador interno salta una fila si tiene menos de dos campos o si falla int(row[1]). Añade al total los valores convertidos válidos. Para las filas ["lamp", "8"], ["desk"], ["chair", "bad"] y ["shelf", "5"], ¿qué pareja final se comunica?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
Pregunta 10 de 10
class ImportDataError(Exception): pass, el código que realiza la llamada captura solo ValueError. ¿Qué ocurre cuando su función auxiliar lanza ImportDataError?Mostrar respuestaOcultar respuesta
Guarda esta unidad para ver esta respuesta.
¿Te atascas con una pregunta tuya? Ayuda con Tareas
Términos Clave
A
Acumulador
errors empieza en 0 y aumenta en 1 cada vez que el bucle encuentra un registro de nivel de error.Archivo cerrado
f.closed es True y f.read() lanza un ValueError sobre el acceso a un archivo cerrado.Archivo de texto
AttributeError
"hi".push("!") provoca AttributeError porque una cadena de Python no tiene ningún método llamado push.B
Bloque try
C
Cabecera
product,stock,price da nombre a las columnas y no debe pasarse como datos a una conversión a entero.Cadena sin procesar
r para conservar las barras invertidas como caracteres literales en lugar de interpretarlas como secuencias de escape normales.r"C:\new\table.txt" conserva los separadores que, de otro modo, iniciarían secuencias de escape de salto de línea y tabulación.Campo
Campo adicional
None.Campo ausente
None.name,score, la fila Ana tiene una puntuación ausente; en cambio, Ana, contiene una cadena de puntuación vacía.Carácter de salto de línea
"\n" en una cadena de Python, marca un cambio de línea; la última línea de un archivo puede no tener terminador de línea."\n" añade otro salto de línea, salvo que se cambie el terminador de la impresión.Clase base de excepción
Cláusula else
Cláusula finally
Codificación
Código de salida
sys.exit("Missing input") imprime el mensaje en la salida de errores y termina con el código de salida 1.Código que realiza la llamada
Creación de directorios
mkdir(parents=True) también puede crear las carpetas que falten por encima de la solicitada.output/daily antes de escribir su informe, ya que abrir un archivo de salida nuevo no crea carpetas.Creación exclusiva
FileExistsError si ya existe un archivo allí."x" impide que un informe recién generado sustituya silenciosamente a otro situado en la misma ruta.CSV
"Lopez, Maria",10,8 tiene tres campos porque su primera coma está dentro de un nombre entrecomillado.D
Delimitador
delimiter=";" para que un lector separe name;score en dos campos.DictReader
name,score, puede accederse a una fila con row["score"] aunque se reordenen las columnas.DictWriter
fieldnames=["product", "stock"] exporta esas columnas cuando recibe diccionarios coincidentes.Directorio de trabajo actual
python tools/report.py desde la raíz del proyecto no cambia por sí solo el directorio a la carpeta de herramientas.Directorio padre
parent de una ruta selecciona esa ubicación contenedora.Path("reports/2026/sales.csv"), el directorio padre es la ruta reports/2026.E
Eliminación de espacios en blanco en los extremos
line.strip(), una línea que contiene solo espacios y un salto de línea se convierte en una cadena vacía.Encadenamiento de excepciones
raise ... from err.Entrecomillado
"River, West", mientras que una simple división por comas separaría ese nombre.Error lógico
Escritor CSV
Excepción
int("many") lanza una excepción antes de que se ejecute la siguiente sentencia de ese bloque.Excepción personalizada
Extensión
suffix de una ruta.Path("data/sales.csv") es ".csv", que un programa puede usar al seleccionar archivos de tablas.F
Fallo controlado
fieldnames
writeheader() en un DictWriter imprime los nombres en el orden configurado en fieldnames.FileExistsError
"x" provoca FileExistsError en lugar de sustituir su contenido.FileNotFoundError
Filtro de líneas
"ERROR".G
Gestor de contexto
with, como habilitar el acceso y liberar recursos.I
IndexError
IsADirectoryError
J
Jerarquía de excepciones
K
KeyboardInterrupt
except: sin tipo puede capturar Ctrl+C, mientras que except Exception: permite que la interrupción se propague.KeyError
row["name"] falla cuando la cabecera de la tabla creó en su lugar la clave "Name".M
Manejador de excepciones
Manejador específico
Manejo delegado de excepciones
Marca de orden de bytes
encoding="utf-8-sig" elimina el marcador inicial para que la primera cabecera coincida con el nombre previsto.Memoria intermedia
Mensaje de error
Modo binario
"rb" identifica la entrada de bytes, mientras que los ejemplos de texto usan un modo como "r".Modo de adición al final
"a" para mensajes de ejecución conserva las ejecuciones anteriores, pero el mensaje sigue necesitando su propio salto de línea.Modo de apertura de archivo
open() que selecciona el acceso permitido y cómo trata la apertura el contenido existente en la ruta."a" para conservar mensajes anteriores, mientras que un informe nuevo puede usar "w" para sustituirlos.N
NameError
Nombre sin la última extensión
Path("logs/run.txt"), el nombre sin la última extensión es "run", mientras que el nombre final completo es "run.txt".Número de línea física
line_num del lector identifica la última línea consumida para un registro que abarca dos líneas.O
Objeto de archivo
open() que proporciona al programa métodos para leer o escribir en un archivo abierto.with open("notes.txt", encoding="utf-8") as f:, el nombre f hace referencia al objeto de archivo.Objeto Path
Path("data") / "scores.txt" construye una ubicación que open() puede aceptar directamente.P
Patrón de rutas con comodines (glob)
* que coincide con texto variable dentro del directorio seleccionado.Path("logs").glob("*.txt") encuentra rutas de archivos de texto coincidentes; ordenarlas proporciona un orden de procesamiento predecible.PermissionError
Posición en el archivo
f.read() haya consumido el contenido restante, una segunda lectura devuelve una cadena vacía.Propagación
R
Recuperación por registro
Registro
Relanzamiento de excepciones
raise sin argumentos, permitiendo una acción local sin tratar el fallo como resuelto.Ruta
data/notes.txt designa un archivo de texto dentro de la carpeta de datos situada bajo el directorio de trabajo actual.Ruta absoluta
/ en sistemas de tipo Unix o la raíz de una unidad en Windows./Users/maya/data/notes.txt no depende del directorio de trabajo actual.Ruta relativa
project/scripts hace que ../data/notes.txt apunte a la carpeta de datos vecina del proyecto.S
Sentencia raise
raise ValueError("amount must be positive") antes de calcular.Sentencia with
with se cierra incluso cuando convertir una línea dentro del bloque provoca un error.SystemExit
sys.exit() fuera de la rama ordinaria de Exception.sys.exit("Missing data") lanza SystemExit con un mensaje y un código de fallo que un manejador ordinario de Exception no captura.T
Terminador de registro
"\r\n".newline="" permite que el escritor proporcione sus propios terminadores sin una segunda capa de conversión.Traza de la excepción
Truncamiento
"w" destruye los registros anteriores aunque el programa nunca llegue a una llamada de escritura.TypeError
"5" y 3 provoca TypeError porque la suma de cadenas no acepta un número entero como segundo operando.U
UnicodeDecodeError
encoding="utf-8".UTF-8
encoding="utf-8" al abrir un archivo de texto guardado como UTF-8 para que sus letras acentuadas se descodifiquen correctamente.V
Validación
ValueError
"3.5" es un tipo de entrada permitido para int(), pero no representa un entero y provoca ValueError.Vinculación de una excepción a un nombre
as para poder examinar su tipo o mensaje dentro de ese manejador.except ValueError as err:, imprimir err muestra el mensaje; la vinculación se elimina después.W
writerow
writer.writerow(["Ana", 8.5]) para un registro de dos campos, no una cadena ya unida.writerows
writerows() para guardar varios registros en una sola llamada.Z
ZeroDivisionError
Sobre esta unidad
Crea tus propios Materiales de Estudio
Convierte tus notas, diapositivas y documentos en Guías de Estudio, Preguntas de Práctica, Flashcards y 6 herramientas más.