Restar 80 a un saldo de 30 es una operación matemática válida: el resultado es -50. Sin embargo, una aplicación bancaria puede tener la regla «no permitas retirar más dinero del disponible».
raise sirve para decir: «desde el punto de vista de este programa, esta situación no es válida».
Detectar una regla incumplida dentro de una función y señalarla con raise en el punto correcto.
Una regla de negocio necesita una señal, no un valor ambiguo
Podrías devolver None, False o -1 cuando algo no está permitido. El problema es que quien llama a la función debe recordar qué significa ese valor especial.
def retirar(saldo, cantidad):
if cantidad > saldo:
raise ValueError("Saldo insuficiente")
return saldo - cantidad
print(retirar(100, 30))En el caso válido, la función devuelve el nuevo saldo. En el caso inválido, no finge un resultado: lanza una excepción con un mensaje que explica la regla incumplida.
raise corta el camino normal en el punto exacto del problema
def validar_edad(edad):
if edad < 0:
raise ValueError("La edad no puede ser negativa")
return edad
print(validar_edad(18))Si la condición del if se cumple, la función termina en ese instante mediante la excepción. No necesitas añadir un else para el camino válido: si no hubo raise, la ejecución continúa.
Quien llama decide si puede recuperarse
def retirar(saldo, cantidad):
if cantidad > saldo:
raise ValueError("Saldo insuficiente")
return saldo - cantidad
try:
print(retirar(30, 80))
except ValueError as error:
print(error)La función retirar() se ocupa de proteger la regla. El código exterior decide cómo presentar el problema. Esta separación hace que la misma función pueda reutilizarse en una web, una aplicación de escritorio o una prueba automática.
Escala la señal solo cuando aporta significado
“No puedes retirar más que el saldo.”
raise ValueError(...) expresa que el valor no es aceptable.
SaldoInsuficienteError merece existir cuando otros errores requieren respuestas distintas.
Escribe la condición que detecta la regla rota y lanza ValueError. El código exterior ya decide cómo recuperarse.
Saldo insuficiente
La salida aparecerá aquí.
Necesito una pista
- Compara
cantidadconsaldo. - Dentro del
if, usaraise ValueError("Saldo insuficiente").
Ver una solución razonada
def retirar(saldo, cantidad):
if cantidad > saldo:
raise ValueError("Saldo insuficiente")
return saldo - cantidad
try:
print(retirar(20, 50))
except ValueError as error:
print(error)Ampliación: cuándo crear una excepción propia
Si tu aplicación necesita distinguir saldo insuficiente, cuenta bloqueada y límite diario para responder de forma diferente, un tipo como SaldoInsuficienteError puede aportar significado. No hace falta crear una clase nueva para cada raise.
No uses excepciones para decisiones normales
Que una persona elija «salir» de un menú no es excepcional; es una opción normal y se maneja con if. Una excepción encaja mejor cuando una operación no puede cumplir su contrato.
Esta diferencia evita convertir el flujo cotidiano del programa en una cadena de try/except.
La prueba de comprensión es poder explicar quién es responsable de qué
- La función detecta una condición inválida y usa
raise. - El código que llama puede capturar la excepción si sabe recuperarse.
- Una excepción propia se crea por significado, no por decorar el código.
Si sabes cuándo preferir raise frente a devolver un valor especial, puedes continuar.