comment
IRC Chat
play_arrow
Este sitio utiliza cookies propias y de terceros. Si continúa navegando consideramos que acepta el uso de cookies. OK Más Información.

Manejo de Excepciones en Python

  • 0 Respuestas
  • 2093 Vistas

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Barlan

  • *
  • Underc0der
  • Mensajes: 89
  • Actividad:
    0%
  • Reputación 0
  • "The demons of my own design"
    • Ver Perfil
  • Twitter: @BarlanV
« en: Mayo 21, 2015, 02:55:35 pm »

Manejo de Excepciones en Python


Citar
Las excepciones son errores detectados por Python durante la ejecución del programa. Cuando el intérprete se encuentra con una situación excepcional, como el intentar dividir un número entre 0 o el intentar acceder a un archivo que no existe, este genera o lanza una excepción, informando al usuario de que existe algún problema.

En Python, contamos con 3 palabras reservadas (y una palabra opcional) para el manejo de excepciones:
  • try
  • except
  • finally
  • else (solo en algunos casos)

Además, contamos con tipos de errores definidos por Python.
Te describiré los principales (o los más comunes):

  • ImportError: Ocurre cuando Python no encuentra el modulo que intentamos importar.
  • IndexError: Cuando nosotros buscamos algo en una tupla o diccionario más alla de lo que realmente posee (ejemplo: Leer el valor #5 de una tupla que contiene solo 3 cosas).
  • KeyError: Cuando no se encuentra una clave en un Diccionario.
  • KeyboardInterrupt: Ocurre cuando nosotros presionamos Ctrl + C. Generalmente presionamos esas teclas cuando caemos en un bucle infinito y queremos pararlo sin cerrar la consola.
  • NameError: Ocurre cuando usamos una variable que no existe.
  • SyntaxError: Se muestra cuando escribimos mál alguna linea de código. Ejemplo: Usar print sin los paréntesis (Python 3.4)
  • TypeError: Ocurre cuando usamos un método en un tipo de variable que no lo posee. Ejemplo: Buscar una clave en una tupla (Usamos un método de un diccionario en una tupla).
  • ValueError: Valor del argumento no apropiado (cuando le designamos un valor a un tipo de variable que no es para eso).

Si buscas más tipos de errores, consulta la documentación oficial de Python 3.4: No tienes permisos para ver links. Registrate o Entra con tu cuenta


Bloque Try-Except


En try, nosotros colocaremos el código que puede llegar a un error.
En except, "atraparemos" el error lanzado por el interprete para evitar que el programa se detenga.

Código: Python
  1. try:
  2.     print(10 / 0)
  3. except:
  4.     print("No se puede dividir entre cero!")
  5.  

Lo anterior trataría de dividir 10 entre 0 (lo cual es imposible).
Si nosotros no escribimos el bloque except... ocurre lo siguiente:

Citar
Traceback (most recent call last):
  File "C:\Users\Barlan\Desktop\ejemplos.py", line 1, in <module>
    print(10 / 0)
ZeroDivisionError: division by zero

Nos lanza un error tipo ZeroDivisionError (Error de división entre cero), lo cual nos indica que no se puede dividir un numero entre 0.

Pero si nosotros escribimos el bloque except...



Como podemos ver, el programa atrapa el error, y evita que se interrumpa a la fuerza el programa a causa de ello.



Podemos también esperar un tipo de error (de los mencionados al principio):

Código: Python
  1. try:
  2.     x = open("Hola.txt", "r")
  3.     print(x)
  4. except (IOError):
  5.     print("No se encontró el archivo.")
  6.  
  7. print("Ja! Seguí ejecutandome ;)")
  8.  

Si el archivo "Hola.txt" no existe en el directorio donde se encuentra el archivo .py, nos lanzará un error tipo IOError.
Para evitar que se cierre el programa, atrapamos ese error con except, e imprimimos que no se encontró el archivo.

Y como el programa no se cerró, se imprimirá "Ja! Segui ejecutandome ;) ")



También podemos atrapar varios tipos de errores:

Código: Python
  1. try:
  2.     x = open("Hola.txt", "r")
  3.     y = x.readlines()
  4.     print(y[5])
  5. except (IOError, IndexError):  # Posiblemente ocurra alguno de estos 2 errores)
  6.     print("Ocurrio un problema.")
  7.  
  8. print("Ja! Seguí ejecutandome ;)")
  9.  



Uso de Else en Excepciones


Usamos else cuando en el bloque try, no se produjo ningún error.
Además, usar else evita que añadamos más lineas de código al try, evitando así más posibles errores.

Código: Python
  1. import sys
  2.  
  3. for arg in sys.argv[1:]:
  4.     try:
  5.         f = open(arg, 'r')
  6.     except IOError:
  7.         print('no pude abrir', arg)
  8.     else:
  9.         print(arg, 'tiene', len(f.readlines()), 'lineas')
  10.         f.close()
  11.  

El programa anterior importa un modulo: sys.
Este modulo tiene un método de leer argumentos al momento de ejecutar nuestro programa (argv)
Después del nombre del programa, nosotros escribimos el nombre del archivo de texto a leer.

El programa tratará de calcular cuantas lineas tiene el archivo.
Si el programa no encuentra el archivo, nos lanza un error:

Citar
no pude abrir [nombre del archivo de texto]

Pero en caso de que si pudimos leer el contenido y calcular las lineas, else se encargará de notificarlo:


Citar
Hola.txt tiene 5 lineas



El bloque finally


El bloque de instrucciones finally se ejecutará siempre, sin importar si ocurrió algún error o no.

Código: Python
  1. try:
  2.     print(x / 10)
  3. except (NameError):
  4.     print("Error. No existe la variable 'x'")
  5. else:
  6.     print("Soy el else.")
  7. finally:
  8.     print("Yo me ejecuto porque se me pega la gana! Thug Life 8)")
  9.  

Generalmente se usa para labores de limpieza (como limpiar la pantalla, o pasar a otra función... etc).



raise


raise nos permite crear nuestras propias excepciones (usando como base las pre-establecidas por Python).
Ejemplo:

Código: Python
  1. >>> raise NameError('Hola')
  2. Traceback (most recent call last):
  3.   File "<stdin>", line 1, in ?
  4. NameError: Hola
  5.  

Aquí forzamos a que ocurriera una Excepción tipo NameError, seguido de un mensaje personalizado.

Otro ejemplo:

Código: Python
  1. try:
  2.     raise NameError("Hola")
  3. except NameError:
  4.     print("Voló una excepción!")
  5.     raise
  6.  

Vemos que raise está solo. Esto significa que hubo una excepción, pero que no quisimos manejarla. Por lo que print() hará el resto.



Excepciones desde clases


Citar
Los programas pueden nombrar sus propias excepciones creando una nueva clase excepción. Las excepciones, típicamente, deberán derivar de la clase Exception, directa o indirectamente. Por ejemplo:

Código: Python
  1. class MiError(Exception):
  2.     def __init__(self, valor):
  3.         self.valor = valor
  4.  
  5.     def __str__(self):
  6.         return repr(self.valor)
  7.  
  8. try:
  9.     raise MiError(2*2)
  10. except Exception as e:
  11.     print("Ocurrió una excepción. Valor:", e)
  12.  
  13. raise MiError("Oops! Un error!")
  14.  

Primero, llegamos al try/except:
Tratamos de calcular 2*2.
Entonces generamos una excepción.

Citar
Ocurrió una excepción. Valor: 4

Luego, forzamos a la clase a que nos genera una excepción con el mensaje "Oops! Un error!"



Citar
Una cláusula finally siempre es ejecutada antes de salir de la declaración try, ya sea que una excepción haya ocurrido o no. Cuando ocurre una excepción en la cláusula try y no fue manejada por una cláusula except (o ocurrió en una cláusula except o else), es relanzada luego de que se ejecuta la cláusula finally.

Código: Python
  1. def dividir(x, y):
  2.     try:
  3.         result = x / y
  4.     except ZeroDivisionError:
  5.         print("¡División por cero!")
  6.     else:
  7.         print("El resultado es: ", result)
  8.     finally:
  9.         print("Instrucción finally.")
  10.  
  11. dividir(2,1)
  12. dividir(2,0)
  13. dividir("hi", "sudo")
  14.  

Citar
El resultado es:  2.0
Instrucción finally.
¡División por cero!
Instrucción finally.

Traceback (most recent call last):
  File "ejemplos.py", line 13, in <module>
    dividir("hi", "sudo")
  File "ejemplos.py", line 3, in dividir
    result = x / y
TypeError: unsupported operand type(s) for /: 'str' and 'str'

Como podemos ver, no manejamos el error TypeError en el exception, por lo que el programa se interrumpe, y procede a imprimir el mensaje de error.



La "acción de limpieza"


Llegará un momento en el que el objeto creado ya no es requerido en más lineas de código. Por ejemplo, al leer un archivo y guardar su contenido en una variable, ya no necesitaremos tener el archivo abierto (esto puede provocar errores):

Código: Python
  1. for linea in open("miarchivo.txt"):
  2.     print(linea, end="")
  3.  

Citar
El problema con este código es que deja el archivo abierto por un periodo de tiempo indeterminado luego de que esta parte termine de ejecutarse. Esto no es un problema en scripts simples, pero puede ser un problema en aplicaciones más grandes. La declaración with permite que objetos como archivos sean usados de una forma que asegure que siempre se los libera rápido y en forma correcta:

Código: Python
  1. with open("miarchivo.txt") as f:
  2.     for linea in f:
  3.         print(linea, end="")
  4.  

La instrucción with nos permite hacer algo solo durante algunas lineas de código. Cuando esa linea termine su trabajo, automáticamente el archivo de texto se cerrará, evitando posibles errores futuros.




Errores, sugerencias y críticas abajo en los comentarios.
Te ha hablado Barlan y te deseo... buenas noches.
« Última modificación: Mayo 22, 2015, 09:33:43 pm por Barlan »


 

¿Te gustó el post? COMPARTILO!



[Código] Yardas a metros - Metros a yardas [Python]

Iniciado por LucaSthefano

Respuestas: 0
Vistas: 1420
Último mensaje Mayo 29, 2011, 01:27:34 am
por LucaSthefano
Python phpmyadmin "BruteForce"

Iniciado por linkgl

Respuestas: 2
Vistas: 2548
Último mensaje Agosto 19, 2011, 12:14:37 pm
por linkgl
Python Trojan - By "bLiNdFiR3"

Iniciado por d33k40

Respuestas: 1
Vistas: 2112
Último mensaje Abril 03, 2010, 11:01:59 pm
por Dharok
Python keylogger - by "bLiNdFiR3"

Iniciado por d33k40

Respuestas: 0
Vistas: 2059
Último mensaje Abril 07, 2010, 03:30:22 am
por d33k40
[Código] Entero / No Entero [Ejercicio - Python]

Iniciado por LucaSthefano

Respuestas: 0
Vistas: 1388
Último mensaje Mayo 29, 2011, 01:24:09 am
por LucaSthefano