9/30/24, 8:50 AM clase-9-2-gestion-errores.
ipynb - Colab
keyboard_arrow_down Gestión de errores (Excepciones)
En el transcurso de la clases se han encontrado varios tipos de errores en Python, como al intentar dividir entre cero, usar un índice fuera de
rango de una cadena o acceder a una variable no definida.
Estos errores se conocen como excepciones (Exceptions) en Python, y ocurren cuando el programa encuentra una situación que no puede
manejar durante la ejecución.
Veamos abajo algunos ejemplos de errores:
1/0
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
<ipython-input-3-9e1622b385b6> in <cell line: 1>()
----> 1 1/0
ZeroDivisionError: division by zero
__alsdfjknnlaklk * 1
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-4-944d36acff4a> in <cell line: 1>()
----> 1 __alsdfjknnlaklk * 1
NameError: name '__alsdfjknnlaklk' is not defined
"hola"[4]
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-5-029484dc3f38> in <cell line: 1>()
----> 1 "hola"[4]
IndexError: string index out of range
Estos errores pueden ser "capturados" para evitar que el programa se detenga de manera abrupta. Esto se logra utilizando bloques
try/except , que permiten manejar las excepciones de forma controlada.
try:
BLOQUE DE CODIGO QUE PUEDE GENERAR EL ERROR
except ERROR1:
BLOQUE QUE EJECUTO SI SUCEDE EL ERROR 1
except ERROR2:
BLOQUE QUE EJECUTO SI SUCEDE EL ERROR 2
except:
BLOQUE QUE EJECUTO SI SUCEDE UN ERROR QUE NO ES ERROR1 o ERROR2 (un else de los ERRORES)
finally:
BLOQUE OPCIONAL QUE EJECUTO DESPUÉS DEL BLOQUE try O DEL ERROR
A continuación, veamos un ejemplo de código que valida una entrada, incluyendo el manejo de errores mediante la estructura try-except :
es_valido = False
while not es_valido:
ingreso = input("Ingrese un número mayor a cero: ")
num = int(ingreso)
if num > 0:
es_valido = True
else:
print("Ingreso inválido!!")
print(f"Ingresó {num}")
[Link] 1/5
9/30/24, 8:50 AM [Link] - Colab
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[7], line 4
2 while not es_valido:
3 ingreso = input("Ingrese un número mayor a cero: ")
----> 4 num = int(ingreso)
5 if num > 0:
6 es_valido = True
ValueError: invalid literal for int() with base 10: 'asd'
Si ingreso un texto inválido que no puede convertirse en un int, el programa generará un error y se detendrá de forma inesperada. A
continuación, veamos cómo podemos manejar esta situación usando un bloque try/except para evitar que el programa se rompa.
es_valido = False
while not es_valido:
try:
ingreso = input("Ingrese un número mayor a cero: ")
num = int(ingreso)
if num > 0:
es_valido = True
except ValueError:
print(f"Ingreso inválido!! {ingreso} no se puede convertir a int")
print(f"Ingresó {num}")
Ingrese un número mayor a cero: j
Ingreso inválido!! j no se puede convertir a int
Ingrese un número mayor a cero: 5
Ingresó 5
La primera vez ingresé j y eso generó una excepción de tipo ValueError , la cual fue "atrapada" por el bloque except . Esto evitó que el
programa se detuviera abruptamente y permitió mostrar un mensaje indicando el tipo de error que ocurrió.
NOTA IMPORTANTE: Si una expresión genera un error, esa expresión no se termina de calcular (no se completa), entonces la variable num
nunca llega a crearse, y por lo tanto, no podemos usarla dentro del bloque except , ya que no existe en ese contexto.
Veamos el sigiuente ejemplo:
try:
a = 1
b = 0
c = a/b
except:
print(f"División por cero!! {a}/{b}")
print("Y c?:", c)
División por cero!! 1/0
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[12], line 9
6 except:
7 print(f"División por cero!! {a}/{b}")
----> 9 print("Y c?:", c)
NameError: name 'c' is not defined
En el ejemplo anterior c se crea después de que la división de a/b se ha realizado exitosamente, y existe un valor para asignarle. Cualquier
error en la división, evita la creación de c .
Si yo no se que tipo de Exception debe atrapar con el except, Puedo asignar la excepción a una variable y luego imprimir la descripción del
error.
try:
a = 1
b = 0
c = a/b
except Exception as error :
print(f"Hubo un error!! {error}")
[Link] 2/5
9/30/24, 8:50 AM [Link] - Colab
Hubo un error!! division by zero
El texto division by zero es la descrición del error en palabras que Python define para ese tipo de error. Exception es un tipo de error que
represent a todos los posible errores. O sea, cualquier error que haya en el bloque try va a ser capturado.
Vamos el ejemplo del ingreso de numeros anterior:
es_valido = False
while not es_valido:
try:
ingreso = input("Ingrese un número mayor a cero: ")
num = int(ingreso)
if num > 0:
es_valido = True
c = 10//num
print(f"El resultado es {c}")
except Exception as e:
print(f"Hubo un error. Vuelva a intentarlo!! Error: {e}.")
Hubo un error. Vuelva a intentarlo!! Error: invalid literal for int() with base 10: 'asd'.
Hubo un error. Vuelva a intentarlo!! Error: integer division or modulo by zero.
El resultado es 10
Cuando ustedes crean una función, si durante la ejecución de esta se puede dar un error, pueden generar sus propias Excepciones con el
comando raise . Veamos la siguiente consigna:
Crear una función que solicite el ingreso de un número entero. La función debe devolver el número ingresado. Si el
usuario ingresa algo erroneo, debe informar el error, y volver a pedir un nuevo ingreso. Al tercer intento fallo debe
crear una excepción.
def ingreso_num(prompt):
MAX_INTENTOS = 3
intentos = MAX_INTENTOS
while intentos > 0:
ingreso = input(prompt)
try:
num = int(ingreso)
return num # Si se ejecuta esta línea es por que la anterior NO falló
# Puedo retornar un valor y terminar la función desde adentro del try!!
except ValueError:
print(f"Vuelva a intentar. {ingreso} no se puede convertir en int")
intentos -= 1
raise Exception(f"Hubo {MAX_INTENTOS} intentos")
# Despues del raise, la función deja de ejecutarse
print("Esto no se imprime nunca")
# Vamos a llamar la función y equivocarnos cuatro veces
a = ingreso_num("Ingrese un entero")
Vuelva a intentar. qwe no se puede convertir en int
Vuelva a intentar. asd no se puede convertir en int
Vuelva a intentar. zxc no se puede convertir en int
---------------------------------------------------------------------------
Exception Traceback (most recent call last)
Cell In[20], line 2
1 # Vamos a llamar la función y equivocarnos cuatro veces
----> 2 a = ingreso_num("Ingrese un entero")
Cell In[19], line 15, in ingreso_num(prompt)
12 print(f"Vuelva a intentar. {ingreso} no se puede convertir en int")
13 intentos -= 1
---> 15 raise Exception(f"Hubo {MAX_INTENTOS} intentos")
16 # Despues del raise, la función deja de ejecutarse
17 print("Esto no se imprime nunca")
Exception: Hubo 3 intentos
Fíjense en el error que aparece en la última línea del output. Indica el texto Hubo 3 intentos , que corresponde con el texto que el código le
pasa al Exception.
Si cuando llamo a mi función ingreso_num se que puede dar un error, entonces puedo caputar ese error.
try:
# V ll l f ió i
[Link] 3/5
9/30/24, 8:50 AM [Link] - Colab
# Vamos a llamar la función y equivocarnos cuatro veces
a = ingreso_num("Ingrese un entero")
except Exception as e:
print(f"Hubo un error. Error: {e}")
Vuelva a intentar. qwe no se puede convertir en int
Vuelva a intentar. asd no se puede convertir en int
Vuelva a intentar. zxc no se puede convertir en int
Hubo un error. Error: Hubo 3 intentos
Esta manera es la forma correcta de gestionar errores dentro del programa. Las funciones deben verificar sus argumentos y en caso de que no
sean correctos, generar errores para que el programa principal.
Veamos otro ejemplo.
Crear una función que devuelva la posición de un caracter en una cadena. La función recibe dos argumentos: cadena:
str en donde se debe buscar el caracter. c: str caracter que debo buscar. No puede estar vacío.
def index( cadena , c ):
# Controlo que los tipos de datos sean los corrector
if type(cadena) != type("str") or type(c) != type("str"):
raise Exception("Los argumentos deben ser del tipo string")
if c == "":
raise Exception("El caracter a buscar no puede ser una cadena vacía")
if len(c) != 1:
raise Exception("El caracter a buscar no puede ser una cadena de longitud distinta a 1")
i=0
while i<len(cadena):
if cadena[i] == c:
return i
i += 1
return None
print("Caso 1")
try:
res = index( 1 , "a")
except Exception as e:
print(e)
print("Caso 2")
try:
res = index( "asd", 1)
except Exception as e:
print(e)
print("Caso 3")
try:
res = index( "asd", "")
except Exception as e:
print(e)
print("Caso 4")
try:
res = index( "asd", "asd")
except Exception as e:
print(e)
print("Caso 5 - Valido no lo encuentra")
try:
res = index( "aaaaa", "b")
if res == None:
print("No se encontró")
else:
print("Está en la posición {res}")
except Exception as e:
print(e)
print("Caso 6 - Valido lo encuentra")
try:
res = index( "abcde", "b")
if res == None:
print("No se encontró")
else:
print(f"Está en la posición {res}")
except Exception as e:
print(e)
Caso 1
Los argumentos deben ser del tipo string
Caso 2
Los argumentos deben ser del tipo string
[Link] 4/5
9/30/24, 8:50 AM [Link] - Colab
Caso 3
El caracter a buscar no puede ser una cadena vacía
Caso 4
El caracter a buscar no puede ser una cadena de longitud distinta a 1
Caso 5 - Valido no lo encuentra
No se encontró
Caso 6 - Valido lo encuentra
Está en la posición 1
Esta es la forma correcta de crear funciones que controlen los posibles errores antes de que estos sucedan.
[Link] 5/5