Manejo de Errores
## Objetivos de Aprendizaje
- Entender las excepciones de Python
- Usar try/except/finally
- Lanzar excepciones personalizadas
- Manejar tipos de error específicos
## Excepciones vs Errores de Sintaxis
### Errores de Sintaxis
```python
# Estos se detectan antes de que el programa se ejecute
if True
print("Hola")
# File "", line 1
# if True
# ^
# SyntaxError: invalid syntax
```
### Excepciones
```python
# Estas ocurren durante la ejecución
print(10 / 0)
# Traceback (most recent call last):
# File "", line 1, in
# ZeroDivisionError: division by zero
```
## try/except Básico
### Ejemplo Simple
```python
try:
resultado = 10 / 0
except ZeroDivisionError:
resultado = 0
print(resultado) # 0
```
### Capturar Múltiples Excepciones
```python
try:
valor = int(input("Introduce un número: "))
resultado = 10 / valor
except ValueError:
print("¡Eso no es un número válido!")
except ZeroDivisionError:
print("¡No se puede dividir por cero!")
```
### Capturar Todas las Excepciones
```python
try:
resultado = operacion_peligrosa()
except Exception as e:
print(f"Error: {e}")
```
### except Desnudo
```python
try:
resultado = operacion_peligrosa()
except:
print("Algo salió mal")
```
## La Cláusula else
```python
try:
valor = int(input("Introduce un número: "))
resultado = 10 / valor
except ValueError:
print("Entrada inválida")
except ZeroDivisionError:
print("No se puede dividir por cero")
else:
print(f"Resultado: {resultado}") # Solo si no hubo excepción
```
## La Cláusula finally
```python
try:
archivo = open("archivo.txt", "r")
contenido = archivo.read()
except FileNotFoundError:
print("Archivo no encontrado")
finally:
print("Esto siempre se ejecuta")
# archivo.close() # Mejor usar context manager
```
## Tipos Comunes de Excepciones
### Excepciones Incorporadas
| Excepción | Cuando se Lanza |
|-----------|-----------------|
| ZeroDivisionError | División por cero |
| ValueError | Valor incorrecto para la operación |
| TypeError | Tipo incorrecto para la operación |
| IndexError | Índice fuera de rango |
| KeyError | Clave no encontrada en dict |
| AttributeError | Atributo no encontrado |
| FileNotFoundError | El archivo no existe |
| ImportError | Falla la importación del módulo |
### Ejemplos
```python
# IndexError
numeros = [1, 2, 3]
print(numeros[5]) # IndexError: list index out of range
# KeyError
d = {"a": 1}
print(d["b"]) # KeyError: 'b'
# TypeError
print("hola" + 5) # TypeError: can only concatenate str
# ValueError
print(int("abc")) # ValueError: invalid literal
```
## Lanzar Excepciones
### Declaración raise
```python
def dividir(a, b):
if b == 0:
raise ValueError("No se puede dividir por cero")
return a / b
try:
resultado = dividir(10, 0)
except ValueError as e:
print(e) # No se puede dividir por cero
```
### Lanzar sin Argumento
```python
try:
raise ValueError("Error personalizado")
except ValueError:
print("Lo capturé")
raise # Relanzar la misma excepción
```
## Excepciones Personalizadas
### Definir Clases de Excepción
```python
class ValidationError(Exception):
"""Lanzada cuando la validación falla."""
pass
class PositiveNumberError(ValidationError):
"""Lanzada cuando el número no es positivo."""
def __init__(self, valor):
self.valor = valor
super().__init__(f"Esperado número positivo, obtenido {valor}")
# Usar excepciones personalizadas
def procesar_numero(n):
if n < 0:
raise PositiveNumberError(n)
return n * 2
try:
procesar_numero(-5)
except PositiveNumberError as e:
print(e) # Esperado número positivo, obtenido -5
```
## Jerarquía de Excepciones
```text
BaseException
├── SystemExit
├── KeyboardInterrupt
└── Exception
├── StopIteration
├── ArithmeticError
│ ├── FloatingPointError
│ ├── OverflowError
│ └── ZeroDivisionError
├── LookupError
│ ├── IndexError
│ └── KeyError
├── OSError
│ ├── FileNotFoundError
│ └── PermissionError
└── ...
```
## Capturar Jerarquía de Excepciones
```python
# Capturar todos los errores aritméticos (incluye ZeroDivisionError, OverflowError)
try:
resultado = 10 / 0
except ArithmeticError:
print("Error matemático")
# Esto también captura ZeroDivisionError ya que es subclase
```
## Patrones Prácticos
### Excepciones en Funciones
```python
def division_segura(a, b):
try:
return a / b
except ZeroDivisionError:
return None
resultado = division_segura(10, 0)
if resultado is None:
print("La división falló")
```
### Patrón de Reintento
```python
import time
def reintentar(func, max_intentos=3, retraso=1):
for intento in range(max_intentos):
try:
return func()
except Exception as e:
if intento == max_intentos - 1:
raise
print(f"Intento {intento + 1} falló: {e}")
time.sleep(retraso)
```
### Con Recursos
```python
try:
with open("archivo.txt", "r") como archivo:
contenido = archivo.read()
except FileNotFoundError:
contenido = ""
```
## Mejores Prácticas
1. **Sé específico** - Captura excepciones específicas, no `except:` desnudos
2. **Limpia** - Usa `finally` o context managers
3. **Relanza** - Permite que las excepciones se propaguen cuando sea apropiado
4. **No supres** - No captures excepciones en silencio sin acción
5. **Excepciones personalizadas** - Crea excepciones específicas para tu dominio
```python
# Bien
try:
resultado = int(entrada_usuario)
except ValueError:
print("Por favor introduce un número válido")
# Mal
try:
resultado = int(entrada_usuario)
except:
pass
```
## Resumen
- Errores de sintaxis: capturados antes de la ejecución
- Excepciones: ocurren durante la ejecución
- Usa `try/except` para manejar excepciones
- `except TipoExcepcion` captura excepciones específicas
- `except Exception as e` captura el objeto de error
- `else` se ejecuta si no hubo excepción
- `finally` siempre se ejecuta
- `raise` dispara una excepción
- Crea excepciones personalizadas extendiendo `Exception`
- Usa context managers (`with`) para limpieza de recursos
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →