Pythonizate "Aprendiendo a programar"
Índice
¡Hola mis queridos entusiastas de la programación! En el post del día de hoy vamos a hablar sobre la identificación de errores y el manejo de excepciones.
¿Que es un error?
Normalmente en nuestros programas pueden ocurrir varios tipos de fallos y siempre que ocurre uno Python nos arroja un aviso indicando que ha ocurrido algo y que se ha detenido la ejecución del programa, entre estos errores están:
- Errores sintácticos: Estos errores están ligados a la sintaxis, que es la escritura de las instrucciones.
Por ejemplo:
Input
>>> print("Steemit)
Output
File "", line 1
print("Steemit)
^
SyntaxError: EOL while scanning string literal
Nos indica que mientras se realizaba el escaneo de la instrucción se produjo un error por la falta de la comilla para cerrar la instrucción.
Input
>>> pint("Steemit")
Output
Traceback (most recent call last):
File "", line 1, in <module>
NameError: name 'pint' is not defined
Otro error común es cuando nos equivocamos escribiendo las instrucciones. En este caso, está esperando una función llamada pint
y esta no está definida.
Los errores sintácticos se pueden identificar antes de ejecutar el programa, la mayoría de los entornos de desarrollo nos informan que algo no va bien para que lo arreglemos y en el peor de los casos el programa lanzará el error con el pertinente aviso.
- Errores semánticos: Estos errores están asociados con el uso, es decir, la sintaxis está bien, pero debido a una determinada circunstancia puede no funcionar como se espera.
Un ejemplo muy común ocurre cuando leemos un valor por teclado e intentamos realizar una operación matemática directamente, sin convertirlo antes a un número. Por ejemplo:
Input
n = input("Introduce un numero: ")
m = 6
print("{}/{}= {}"(n,m,n/m))
Output
Introduce un numero: 4
Traceback (most recent call last):
File "<pyshell#8>", line 1, in <module>
print("{}/{}= {}"(n,m,n/m))
TypeError: unsupported operand type(s) for /: 'str' and 'int'
Este error es claro, porque hemos leído una cadena y lo estamos intentando dividir por un número, esto no es posible, en este caso tenemos que asegurarnos de transformar la cadena a un entero o un float. Por ejemplo:
Input
n = int(input("Introduce un numero: "))
m = 6
print("{}/{}= {}".format(n,m,n/m))
Output
Introduce un numero: 5
5/6= 0.8333333333333334
¿ Qué sucedería si el usuario introduce una letra en vez de un número? Vamos a averiguarlo
Input
n = int(input("Introduce un numero: "))
m = 6
print("{}/{}= {}".format(n,m,n/m))
Output
Introduce un numero: aaa
Traceback (most recent call last):
File "C:/Users/Ramses Garate/Documents/Mis Documentos/Ramses/Ejercicios Programacion/Python/prueba1.py", line 1, in <module>
n = int(input("Introduce un numero: "))
ValueError: invalid literal for int() with base 10: 'aaa'
Nos lanza otro error, es lógico porque no podemos convertir una cadena de caracteres a un entero. Entonces, ¿Existirá alguna forma de adelantarnos a los hechos para evitar estos errores y que el programa no se detenga? Claro que sí, creando estados de excepción para que el programa siga ejecutándose aunque ocurra un error.
¿Qué es una excepción?
Una excepción es un bloque de código que ocurre durante la ejecución del programa y nos permite continuar con su ejecución aunque ocurra un error.
La sintaxis de una excepción es la siguiente:
try:
Usted hace sus operaciones aquí;
except ExceptionI:
Si hay ExcepciónI, entonces ejecuta este bloque.
except ExceptionII:
Si hay ExceptionII, entonces ejecuta este bloque.
else:
Si no hay excepción, ejecuta este bloque.
finally:
Código que siempre se va a ejecutar al finalizar el bucle haya o no un error.
En el bloque try:
( de intentar) vamos a colocar todo el código propenso a errores y luego lo seguiremos de un bloque except:
(de excepción), dentro de este bloque colocaremos el código que se ejecutará en caso de que ocurra un error. Por ejemplo:
Input
try:
n = int(input("Introduce un numero: "))
m = 6
print("{}/{}= {}".format(n,m,n/m))
except:
print("Ha ocurrido un error, introduce un numero")
Output
Introduce un numero: aaa
Ha ocurrido un error, introduce un numero
Como podemos observar, cada vez que ocurra un error el programa nos va a mostrar el mensaje "Ha ocurrido un error, introduce un número", si colocamos este programa dentro de un bucle while(True)
, se crearía un bucle infinito y si se presenta un error nuestro programa no se detendría.
Input
while(True):
try:
n = int(input("Introduce un numero: "))
m = 6
print("{}/{}= {}".format(n,m,n/m))
break #Rompe la ejecucion del programa si se introduce un numero
except:
print("Ha ocurrido un error")
Output
Introduce un numero: aaa
Ha ocurrido un error
Introduce un numero: jjj
Ha ocurrido un error
Introduce un numero: ff
Ha ocurrido un error
Introduce un numero: 4
4/6= 0.6666666666666666
Las excepciones abarcan mucho más que esto, en primer lugar permiten añadir un bloque de código else
a except
para ejecutar un código en caso de que todo vaya correctamente y ese es el lugar perfecto para colocar el break
de nuestro while
Input
while(True):
try:
n = int(input("\nIntroduce un numero: "))
m = 6
print("{}/{}= {}".format(n,m,n/m))
except:
print("Ha ocurrido un error")
else:
print("Todo ha funcionado correctamente")
break #Rompe la ejecucion si se introduce un numero
Output
Introduce un numero: hfh
Ha ocurrido un error
Introduce un numero: hfh
Ha ocurrido un error
Introduce un numero: 94
94/6= 15.666666666666666
Todo ha funcionado correctamente
El bloque de código else
se va a ejecutar si todo va bien, es decir, si no ocurre una excepción se ejecuta el else
.
Todavía se nos permite agregar otro bloque de código, en este caso el finally:
, este bloque siempre va al final de todo, se ejecutará siempre al final del while
ocurra o no ocurra un error, es indiferente. Por ejemplo:
Input
while(True):
try:
n = int(input("\nIntroduce un numero: "))
m = 6
print("{}/{}= {}".format(n,m,n/m))
except:
print("Ha ocurrido un error")
else:
print("Todo ha funcionado correctamente")
break #Rompe la ejecucion si se introduce un numero
finally:
print("Fin de la iteracion")
Output
Introduce un numero: ahsd
Ha ocurrido un error
Fin de la iteracion
Introduce un numero: 49
49/6= 8.166666666666666
Todo ha funcionado correctamente
Fin de la iteracion
Resumiendo, tenemos cuatro bloques de excepción:
Try
: para capturar cualquier error dentro de un bloque de instrucciones.Except
: para definir el código que se va a ejecutar de presentarse un error.Else
: para definir el código que se va a ejecutar sino ocurre ningún error.Finally
: para definir el código que se va a ejecutar al final haya o no un error.
Múltiples excepciones
Ahora vamos a definir distintas excepciones, eso podemos hacerlo porque cada vez que ocurre un error dentro del try
se produce una excepción, cada excepción tiene su propio identificador, este identificador lo podemos capturar y luego guardarlo en una variable para visualizarlo.
Si ejecutamos el siguiente código:
Input
n = input("Introduce un numero: ")
10/n
Output
Introduce un numero: 3
Traceback (most recent call last):
File "C:/Users/Ramses Garate/Documents/Mis Documentos/Ramses/Ejercicios Programacion/Python/prueba1.py", line 2, in <module>
10/n
TypeError: unsupported operand type(s) for /: 'int' and 'str'
Podemos notar que en la ultima linea nos indica el nombre del error TypeError
.
Si colocamos una excepción sin su identificador no podremos saber el tipo de excepción, veamos el siguiente ejemplo.
Input
try:
n = input("Introduce un numero: ")
10/n
except:
print("Error")
Output
Introduce un numero: 5
Error
Como podemos notar ahora no nos muestra el tipo de error, pero hay un truco para poder conocer el identificador de nuestra excepción, colocando except Exception as e:
de esta manera vamos a guardar una excepción genérica en la variable e
y luego dentro de esta excepción colocamos print( type(e)._name_)
esto es para conseguir el nombre del error, el código quedaría de la siguiente manera:
Input
try:
n = input("Introduce un numero: ")
10/n
except Exception as e:
print(type(e).__name__)
Output
Introduce un numero: 5
TypeError
Ahora podemos mostrar el error que teníamos antes, sin que se detenga la ejecución del código con la excepción. Este código es simplemente para conseguir el nombre del error, lo entenderán un poco mejor más adelante cuando veamos las clases y la herencia, conociendo el nombre del error podemos encadenar varias excepciones a través de sus identificadores. La excepción para reconocer el nombre del error siempre se coloca de última. Veamos un ejemplo:
Input
try:
n = input("Introduce un numero: ")
10/n
except TypeError:
print("No se puede dividir el numero por una cadena")
except Exception as e:
print(type(e).__name__)
Output
Introduce un numero: 5
No se puede dividir el numero por una cadena
Convertimos el número a un entero y volvemos a ejecutar el código.
Input
try:
n = int(input("Introduce un numero: "))
10/n
except TypeError:
print("No se puede dividir el numero por una cadena")
except Exception as e:
print(type(e).__name__)
Output
Introduce un numero: aaa
ValueError
Ahora nuestro código nos manda un nuevo error ValueError
, como ya les dije antes, esto es por la excepción genérica que nos muestra el nombre de las excepciones. Vamos a colocar esta excepción debajo de TypeError
.
Input
try:
n = int(input("Introduce un numero: "))
10/n
except TypeError:
print("No se puede dividir el numero por una cadena")
except ValueError:
print("Debes introducir un numero, no un cadena de caracteres")
except Exception as e:
print(type(e).__name__)
Output
Introduce un numero: aaaa
Debes introducir un numero, no un cadena de caracteres
Ahora nuestro código nos captura el error ValueError
y nos muestra el mensaje "Debes introducir un número, no un cadena de caracteres".
Todavía podemos añadir otra excepción, está el caso de introducir el número cero.
Input
try:
n = int(input("Introduce un numero: "))
10/n
except TypeError:
print("No se puede dividir el numero por una cadena")
except ValueError:
print("Debes introducir un numero, no un cadena de caracteres")
except Exception as e:
print(type(e).__name__)
Output
Introduce un numero: 0
ZeroDivisionError
Esto provoca un error porque no se puede dividir nada por cero, porque es una indeterminación y nos da un error de ZeroDivisionError
, podemos crear otra excepción para este error.
Input
try:
n = int(input("Introduce un numero: "))
10/n
except TypeError:
print("No se puede dividir el numero por una cadena")
except ValueError:
print("Debes introducir un numero, no un cadena de caracteres")
except ZeroDivisionError:
print("No se puede dividir por cero, prueba otro numero")
except Exception as e:
print(type(e).__name__)
Output
Introduce un numero: 0
No se puede dividir por cero, prueba otro numero
Con estos ejemplos podemos ver que se pueden encadenar todas las excepciones que sean necesarias para que nuestro programa continúe su ejecución.
Con este post terminamos oficialmente la parte básica del tutorial Pythonizate.
Pido disculpas por la tardanza en publicar este post, andaba en terminando clases y con full evaluaciones.
La próxima parte del tutorial la comenzare a mediados de septiembre para darme un descanso, de igual forma no te pierdas mis próximas publicaciones porque nos vamos a adentrar en nuevas ramas de la tecnología.
Si tienen alguna duda o consulta no duden en dejarla en los comentarios. ¡Éxitos!
"El ser humano es inteligente por naturaleza, la tecnología es solo un complemento"
╭════════════╮
Sígueme en mi Blog
╰════════════╯