Volver al curso

Python Desde Cero

leccion
9 / 21
beginner
20 horas
Control de Flujo y Funciones

Manejo de Errores con try/except: Codigo Robusto

Lectura
20 min~4 min lectura

Manejo de Errores con try/except: Codigo Robusto

En el mundo real, los programas fallan. Los usuarios ingresan datos incorrectos, los archivos no existen. Un programa robusto debe anticipar estos problemas y manejarlos con elegancia.

Que son las excepciones

Una excepcion es un error durante la ejecucion. Python lanza una excepcion y el programa se detiene si no la manejamos.

numero = int('hola')  # ValueError: no se puede convertir a entero
print('Esta linea nunca se ejecuta')
La estructura try/except
try:
    resultado = int('hola')
except ValueError:
    print('Error: no se pudo convertir el valor a numero')

print('El programa continua...')

El programa ya no explota. Capturamos el error y lo manejamos apropiadamente.

Excepciones comunes en Python
Excepcion Cuando ocurre
ValueError Valor incorrecto
TypeError Tipo incorrecto
ZeroDivisionError Division entre cero
FileNotFoundError Archivo no encontrado
IndexError Indice fuera de rango
KeyError Clave inexistente en diccionario
NameError Variable no definida
Capturar multiples excepciones
def dividir(a, b):
    try:
        a = float(a)
        b = float(b)
        return a / b
    except ValueError:
        print('Error: ambos valores deben ser numeros')
        return None
    except ZeroDivisionError:
        print('Error: no se puede dividir entre cero')
        return None

print(dividir(10, 2))
print(dividir(10, 0))
print(dividir('abc', 2))

En una sola linea

try:
    op = int(input('Numero: ')) / int(input('Divisor: '))
except (ValueError, ZeroDivisionError) as error:
    print(f'Error: {error}')
Las clausulas else y finally
try:
    numero = int(input('Ingresa un numero: '))
except ValueError:
    print('Eso no es un numero valido')
else:
    # Se ejecuta SOLO si no hubo excepciones
    print(f'El cuadrado de {numero} es {numero ** 2}')
finally:
    # Se ejecuta SIEMPRE
    print('Gracias por usar el programa')

finally es ideal para cerrar archivos y conexiones a base de datos.

Obtener informacion del error
try:
    lista = [1, 2, 3]
    elemento = lista[10]
except IndexError as e:
    print(f'Error: {e}')
    print(f'Tipo: {type(e).__name__}')
Excepciones personalizadas
class SaldoInsuficienteError(Exception):
    def __init__(self, saldo, monto):
        self.saldo = saldo
        self.monto = monto
        super().__init__(f'Saldo insuficiente: tienes {saldo}, intentas retirar {monto}')

class CuentaBancaria:
    def __init__(self, saldo_inicial):
        self.saldo = saldo_inicial
    
    def retirar(self, monto):
        if monto > self.saldo:
            raise SaldoInsuficienteError(self.saldo, monto)
        self.saldo -= monto
        return self.saldo

cuenta = CuentaBancaria(500)

try:
    cuenta.retirar(200)
    print(f'Retiro exitoso. Saldo: {cuenta.saldo}')
    cuenta.retirar(400)
except SaldoInsuficienteError as e:
    print(f'Error: {e}')
Proyecto: Procesador de datos con manejo de errores
def procesar_ventas(datos_raw):
    ventas_validas = []
    errores = []
    
    for i, dato in enumerate(datos_raw):
        try:
            venta = float(dato)
            if venta < 0:
                raise ValueError(f'Venta negativa: {venta}')
            ventas_validas.append(venta)
        except ValueError as e:
            errores.append(f'Fila {i+1}: {e}')
        except TypeError as e:
            errores.append(f'Fila {i+1}: Tipo incorrecto')
    
    if not ventas_validas:
        raise RuntimeError('No hay datos validos')
    
    return {
        'total': sum(ventas_validas),
        'promedio': sum(ventas_validas) / len(ventas_validas),
        'maximo': max(ventas_validas),
        'minimo': min(ventas_validas),
        'validos': len(ventas_validas),
        'con_error': len(errores)
    }, errores

datos = ['150.50', '200', 'abc', '-30', '450.75', None, '300', '125']

try:
    stats, errores = procesar_ventas(datos)
    print(f"Total: {stats['total']:.2f}")
    print(f"Promedio: {stats['promedio']:.2f}")
    print(f"Validos: {stats['validos']}")
    print(f"Con error: {stats['con_error']}")
    for error in errores:
        print(f'  - {error}')
except RuntimeError as e:
    print(f'Error critico: {e}')
Buenas practicas
  1. Se especifico: captura la excepcion exacta.
  2. No silencies errores: evita except pass.
  3. Registra errores en produccion con logging.
  4. Usa finally para limpieza de recursos.
  5. Crea excepciones personalizadas para errores de negocio.
# MAL:
try:
    resultado = operar(datos)
except:
    pass

# BIEN:
try:
    resultado = operar(datos)
except ValueError as e:
    print(f'Dato invalido: {e}')
    resultado = valor_por_defecto
💡 Concepto Clave

Revisemos los puntos más importantes de esta lección antes de continuar.

Resumen

  • try/except captura y maneja errores
  • else se ejecuta si no hubo error
  • finally se ejecuta siempre
  • Puedes crear excepciones personalizadas heredando de Exception
  • raise lanza excepciones manualmente

Con estas herramientas, tu codigo maneja situaciones inesperadas con elegancia. En el proximo modulo exploraremos las estructuras de datos de Python!

🧠 Pon a prueba tu conocimiento
¿Cuál es el aspecto más importante que aprendiste en esta lección?
  • Comprendo el concepto principal y puedo explicarlo con mis palabras
  • Entiendo cómo aplicarlo en mi situación específica
  • Necesito repasar algunas partes antes de continuar
  • Quiero ver más ejemplos prácticos del tema
✅ ¡Excelente! Continúa con la siguiente lección para profundizar más.