Manejo de excepciones de Python

Esta guía le brindará una introducción a lo que son las excepciones de Python, los tipos de excepciones más comunes (KeyError, SyntaxError, TypeError) y cómo manejar las excepciones generadas con las cláusulas try, except y finalmente.

Introducción

Una excepción de Python es una construcción utilizada para señalar un evento importante, generalmente un error, que ocurre al ejecutar un programa. Una excepción puede hacer que el programa se detenga si no se “captura” correctamente (es decir, si no se maneja correctamente). Si cree que su programa puede generar una excepción cuando se ejecuta, le resultará útil usar try/except para manejarlas, lo cual veremos en la siguiente sección.

Esta guía le brindará una introducción a las excepciones de Python, los tipos de excepciones más comunes y cómo manejar las excepciones generadas con las cláusulas try y except.

Manejo de excepciones

En el siguiente ejemplo, le pedimos al usuario que ingrese un número y, después de la ejecución, el programa da el valor del número dado al cuadrado. El programa funcionará siempre que ingrese un número como entrada:

1
2
3
while True:
    x = int(raw_input("Please enter a number: "))
    print("%s squared is %s" % (x, x**2))

Cuando ingresa una cadena o cualquier otro carácter que no sea un número, como "uno", el programa generará una excepción "Error de valor":

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
$ python squared.py 
Please enter a number: 3
3 squared is 9
Please enter a number: 4
4 squared is 16
Please enter a number: five
Traceback (most recent call last):
  File "squared.py", line 4, in <module>
    x = int(raw_input("Please enter a number: "))
ValueError: invalid literal for int() with base 10: 'five'

Aquí es donde entra en juego el manejo de excepciones. Debe saber cómo manejar las excepciones correctamente, especialmente en entornos de producción, porque si no se manejan, su programa no sabrá qué hacer y se bloqueará.

Veamos cómo podemos manejar el error anterior. Esto se hace rodeando el programa que cree que podría generar una excepción con una palabra clave try y combinándolo con la siguiente palabra clave except para ejecutar en caso de que se produzca una excepción.

Reescribamos el mismo programa, y ​​esta vez se ocupa de las excepciones que puedan surgir:

1
2
3
4
5
6
while True:
    try:
        x = int(raw_input("Please enter a number: "))
        print("%s squared is %s" % (x, x**2))
    except ValueError:
        print("Please enter a valid number!")

Como puede ver en el programa anterior, el código dentro de la instrucción try se ejecuta primero. Si no se produce ningún error, se ejecuta el resto del código y se omite la instrucción except.

En el caso de que se genere una excepción (como cuando se ingresa una cadena en lugar de un número), el programa ejecuta la declaración excepto que coincide con su declaración try, seguida por el resto del código fuera de try/except bloque, si lo hay.

Vea lo que sucede cuando ejecutamos nuestro código con las declaraciones try/except:

1
2
3
4
5
6
7
8
9
$ python safe_squared.py 
Please enter a number: 3
3 squared is 9
Please enter a number: 4
4 squared is 16
Please enter a number: five
Please enter a valid number!
Please enter a number: 5
5 squared is 25

{.icon aria-hidden=“true”}

Nota: tenga en cuenta que una cláusula except solo manejará las excepciones de su correspondiente cláusula try, incluso si hay varios controladores de cláusulas try/except.

Tipos de excepciones en Python

Python tiene varias excepciones integradas. Echemos un vistazo a algunas de las excepciones más comunes para que pueda tener una perspectiva de lo que son y cómo usarlas.

Excepción KeyError

Este es un error que ocurre cuando usa un diccionario e intenta recuperar una clave que no está presente en el diccionario.

La siguiente es una vista de Django utilizada para autenticar a los usuarios y espera recibir un diccionario que contenga las claves "nombre de usuario" y "contraseña". Si alguna de las claves no se pasa en los datos, el programa generará una excepción de error de clave.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
def authenticate_user(request):
    try:
        email = request.data['username']
        password = request.data['password']

        user = authenticate(email=email, password=password)

        if user and user.is_active:
            return Response(user_details,status=HTTP_200_OK)
        else:
            res = {'error': 'can not authenticate with the given credentials'}
            return Response(res, status=status.HTTP_400_BAD_REQUEST)
    except KeyError:
        res = {'error': 'please provide a username and a password'}

Al usar try/except para capturar la excepción, nuestro usuario verá el error en lugar de colapsar nuestro servidor.

Excepción de error de sangría {#excepción de error de sangría}

Este tipo de excepción se produce cuando el código no tiene la sangría adecuada. En lugar de usar llaves para especificar el alcance, Python usa sangría, por lo que es importante que la sangría sea correcta, que es el propósito de esta excepción.

Escribamos una función que verifique si un número es par:

1
2
3
4
5
6
7
8
def is_even(number):
    if number % 2 == 0:
    print(" %s is an even number" % (number))
    else:
    print("%s is an odd number" % (number))

print(is_even(1))
print(is_even(2))

La función dará como resultado un error de sangría en las líneas 2 y 4 porque espera que el código tenga una sangría de 8 espacios, no de 4.

Si ejecuta el programa, dará el siguiente resultado:

1
2
3
4
5
$ python is_even.py 
  File "is_even.py", line 3
    print(" %s is an even number" % (number))
        ^
IndentationError: expected an indented block

Excepción de error de sintaxis {#excepción de error de sintaxis}

Este es uno de los tipos de excepciones más comunes en Python. Ocurre cuando hay un error en la sintaxis de su código.

Veamos el siguiente ejemplo:

1
2
3
4
5
6
7
def is_odd(n):
    if n % 2 != 0:
        print(it's odd)
    else:
        print("not odd")

print(is_odd(7))

La salida de este código dará como resultado una sintaxis no válida en la línea 3 porque la cadena "es impar" no está entre comillas:

1
2
3
4
5
$ python is_odd.py 
  File "is_odd.py", line 3
    print(it's odd)
                  ^
SyntaxError: EOL while scanning string literal

Tenga en cuenta que hay muchos tipos diferentes de errores de sintaxis, y este es solo un ejemplo.

Excepción de error de tipo {#excepción de error de tipo}

Esta excepción se genera cuando se intenta una operación o función que no es válida para el tipo de datos especificado. En el siguiente ejemplo, la función sum_of_numbers toma 2 argumentos y los suma. Cuando intenta llamar a la función con 3 argumentos, genera una excepción TypeError porque espera solo 2 argumentos:

1
2
3
4
def sum_of_numbers(a, b):
    return a + b

print(sum_of_numbers(1, 2, 7))

Ejecutar este código arroja el siguiente resultado:

1
2
3
4
5
$ python sum_of_numbers.py 
Traceback (most recent call last):
  File "sum_of_numbers.py", line 4, in <module>
    print(sum_of_numbers(1, 2, 7))
TypeError: sum_of_numbers() takes exactly 2 arguments (3 given)

Las cláusulas try/except, else y finally

Hay varios otros componentes del manejo de excepciones y son las cláusulas else y finally.

Ya hemos podido utilizar sentencias try y catch, que se utilizan para detectar errores. Veamos ahora también las sentencias else y finally.

La cláusula else

La cláusula else se usa para ejecutar código cuando el programa no lanza una excepción. También es mejor usar la cláusula else que agregar código adicional a la cláusula try. Esto se debe a que evita capturar involuntariamente una excepción que no fue generada por el código protegido por las declaraciones try/except.

Considere el ejemplo que usamos al comienzo de este tutorial, pero en su lugar, vamos a ejecutar la instrucción print dentro de la declaración else:

1
2
3
4
5
6
7
while True:
    try:
        x = int(raw_input("Please enter a number: "))
    except ValueError:
        print("Please enter a valid number!")
    else:
        print("%s squared is %s" % (x, x**2))

Ejecutar este código proporciona la misma funcionalidad que antes, excepto que aísla el código int(raw_input(...)) propenso a errores en la declaración try, y el código "safe" en else declaración:

1
2
3
4
5
6
7
8
9
$ python else_squared.py 
Please enter a number: 3
3 squared is 9
Please enter a number: 4
4 squared is 16
Please enter a number: five
Please enter a valid number!
Please enter a number: 5
5 squared is 25

La cláusula finally

Esta cláusula está destinada a definir las acciones de limpieza que se deben realizar independientemente de si se generó una excepción o no.

Siempre se debe ejecutar una cláusula finally antes de salir de la instrucción try/except, ya sea que haya ocurrido una excepción o no. Esto generalmente se usa para limpiar, como cerrar un archivo abierto.

Incluyamos la cláusula finally en nuestro ejemplo:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
count = 0

while True:
    try:
        x = int(raw_input("Please enter a number: "))
    except ValueError:
        print("Please enter a valid number!")
    else:
        print("%s squared is %s" % (x, x**2))
    finally:
        print("Ran %s time(s)" % count)

La ejecución de este código es similar a la anterior, excepto que ahora podemos ver cuántas veces se ha ejecutado nuestro ciclo, independientemente de si se generó una excepción o no:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
$ python finally_squared.py 
Please enter a number: 3
3 squared is 9
Ran 1 time(s)
Please enter a number: 4
4 squared is 16
Ran 2 time(s)
Please enter a number: five
Please enter a valid number!
Ran 3 time(s)
Please enter a number: 5
5 squared is 25
Ran 4 time(s)

Conclusión

En esta guía, explicamos brevemente cómo manejar las excepciones en Python usando las instrucciones try/except, incluidos algunos de los componentes opcionales, else y finally. Espero que este tutorial haya aclarado cualquier confusión que haya tenido sobre las excepciones de Python.

Si quieres saber más, puedes encontrar más información en la sección Errores y excepciones de la documentación de Python.

Licensed under CC BY-NC-SA 4.0