Tiza Las materias del CBC
Practicar →

Pensamiento Computacional (090) · Unidad 5 — Entrada, salida y errores

Manejo de errores

try / except deja que el programa siga cuando algo falla. Pero atrapar todo sin mirar esconde los errores en vez de arreglarlos.

Practicar este tema →7 ejercicios que te corrigen paso a paso · gratis, sin cuenta

La explicación

El problema

Un error corta el programa. Si el usuario escribe "hola" donde iba un número, int() tira ValueError y todo lo que venía después no se ejecuta.

try y except

try:
    edad = int(input("Edad: "))
except ValueError:
    print("Eso no es un número")

Python intenta lo del try. Si sale bien, saltea el except. Si falla con ese error, ejecuta el except y el programa sigue.

Los errores que más vas a ver

ValueError         int("hola")         el tipo está bien, el valor no
TypeError          "a" + 1             tipos incompatibles
ZeroDivisionError  10 / 0
IndexError         [1,2][5]            posición que no existe
KeyError           d["pepe"]           clave que no existe
FileNotFoundError  open("no.txt")
NameError          usar una variable no definida
Leer el mensaje de error es media solución. Python te dice el tipo, la línea y muchas veces qué valor lo causó. Un TypeError que menciona NoneType casi siempre significa que una función terminó sin return — lo que vimos en el tema 2.5.

Varios except

try:
    resultado = int(a) / int(b)
except ValueError:
    print("No son números")
except ZeroDivisionError:
    print("No se puede dividir por cero")

Se ejecuta el primero que coincida, igual que un elif.

El except vacío, y por qué no conviene

try:
    ...
except:      # atrapa absolutamente todo
    pass
Esto esconde los errores en vez de manejarlos. Un error de tipeo en un nombre de variable daría NameError, quedaría atrapado ahí, y el programa seguiría como si nada — dando resultados mal sin que nadie se entere. Atrapá el error que esperás, no todos.

Validar en un ciclo

while True:
    try:
        edad = int(input("Edad: "))
        break            # sólo llega acá si el int() funcionó
    except ValueError:
        print("Poné un número entero")

Es el patrón estándar para pedir un dato hasta que sea válido. El break va después de la línea que puede fallar: si falla, nunca se alcanza.

Ejemplo resuelto

Escribir una función que pida un número por teclado y no siga hasta que el usuario escriba uno válido.

def pedir_numero():
    while True:
        try:
            return int(input("Número: "))
        except ValueError:
            print("Eso no es un número entero. Probá de nuevo.")

Cómo corre. Si el usuario escribe 25, el int() funciona, el return devuelve 25 y la función termina. Si escribe hola, el int() falla, se ejecuta el except, y el while True da otra vuelta.

El return hace de break. Está en la misma línea que puede fallar: si int() explota, nunca se llega a devolver nada. Si hubieras escrito
numero = input("Número: ")
return int(numero)   ← el error ocurre acá
el resultado sería el mismo, pero es más fácil equivocarse y poner el return afuera del try.

Por qué except ValueError y no except a secas. Si el usuario corta el programa con Ctrl+C, un except vacío lo atraparía también y no habría forma de salir. Atrapando sólo ValueError, todo lo demás sigue funcionando normal.

Control: probá con un número, con texto, y con el Enter vacío. Los tres tienen que comportarse como esperás — el vacío también es ValueError.

Dónde se cae la mayoría

Hasta acá la explicación. La práctica es la otra mitad: 7 ejercicios de este tema, en cuatro niveles, que no te dicen sólo si está bien al final sino que te corrigen en cada paso y te explican por qué. Además trae una animación que muestra la idea en movimiento.

Practicar Manejo de errores →

Ver todos los temas de Pensamiento Computacional