17 de mayo de 2016

26. Errores y manejo de excepciones

¿Qué son los errores?

A pesar de lo que alguno pueda pensar, los ordenadores no son ni mucho menos infalibles. Cometen errores, y a todos los niveles. En la transmisión digital, es común la pérdida de información por errores, pero también hay procedimientos que permiten la restauración del código perdido. Es una característica de la digitalización el poder restaurar ciertos errores, sobre todos los relacionados con el ruido.
A nivel de software, nuestros programas tendrán errores.  Algunos evitables, otros inevitables pero tratables. Muchas veces, parte de nuestro código simplemente se escribe para evitar cualquier tipo de error. Y es muy fácil hacer caer a nuestro programa en un error.
Tipos de errores.
  1. Los más fáciles de solucionar son los de sintaxis. El código no se ejecuta porque está mal escrito. Si tenemos un buen editor (IDE) nos irá indicando estos errores, o al ejecutar el código se nos indicará dónde está el error. Es cuestión de escribirlo bien. (En Ninja-ide el código se subraya en rojo, en Geany al compilar o ejecutar indican esos errores).
  2. Error semántico: aunque no tiene errores sintácticos, el programa no hace lo que se desea. Le falta una línea de código, un algoritmo incorrecto...
  3. Error de ejecución o excepciones: aparecen una vez se ejecuta el programa y a éste le ponemos en una situación que no se esperaba, por ejemplo:
    1. Se ha provocado que se divida un número entre 0.
    2. Hemos introducido una cadena de caracteres cuando se pedía un número.
    3. Se accede al lugar 5 de una lista con sólo 3 elementos.
    4. Se intenta leer un archivo que está dañado...
    5. Etc.
Los errores de tipo 1 y 2 son los más fáciles de solucionar, ya que lo que hay que hacer es escribir bien el código o los algoritmos. Los errores del tercer tipo son más difíciles de delimitar, porque su origen puede ser muy complejo. Veremos, a partir de ahora, cómo tratar este tipo de errores.

= = =

Manejo de excepciones

Hemos de tener en cuenta que cuando se produce un error de ejecución o excepción, puede haberse producido dentro de una función o en el programa principal.
Si el error se produce dentro de la función, éste se propaga hacia el código desde donde fue invocada, que puede ser otra función o el programa principal. Si el error no es tratado, y llega al programa principal, se produce la interrupción del mismo.
En el caso de Python, el manejo de excepciones se realiza mediante tres instrucciones: try, except y finally, constituyendo un bloque. 'try' se usa para evaluar un conjunto de instrucciones, 'except' se usa para capturar la excepción y actuar sobre ella o informar al usuario y 'finally' es el código que se ejecuta tras la evaluación de la excepción o del bloque try sin errores (finally no siempre está presente y también es posible tener un bloque finally sin except).
Los bloques except pueden ser genéricos o específicos del error que tratan, y tener más de uno en un bloque.
Por ejemplo, ejecuta este código:
# *-* coding:utf-8 *-*

divisor = 0
dividendo = 200

print dividendo / divisor
Clarísimamente, se generará un error de división entre cero. Podemos ejecutar pues, este código alternativo
# *-* coding:utf-8 *-*

try:
    divisor = int(raw_input("Divisor (escribe cero): "))
    dividendo = int(raw_input("Dividendo: "))
    print dividendo/divisor

except ZeroDivisionError:
    print "Por favor, no sé dividir entre cero"
    
except:
    print "Se ha producido otro tipo de error"
= = =
Para saber más sobre qué error se ha producido , se puede usar el siguiente programa o se puede utilizar la función exc_info del módulo sys (los módulos los veremos más adelante).
# *-* coding:utf-8 *-*

try:
    divisor = int(raw_input("Divisor (escribe cero): "))
    dividendo = int(raw_input("Dividendo: "))
    print dividendo/divisor

except ZeroDivisionError:
    print "Por favor, no sé dividir entre cero"
    
except Exception, ex:
    print "Se ha producido otro tipo de error: " + str(ex)
# *-* coding:utf-8 *-*

import sys

try:
    divisor = int(raw_input("Divisor (escribe cero): "))
    dividendo = int(raw_input("Dividendo: "))
    print dividendo/divisor

except ZeroDivisionError:
    print "Por favor, no sé dividir entre cero"
    
except:
    for i in range(3):
        print("Error inesperado:", sys.exc_info()[i])

No hay comentarios:

Publicar un comentario