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.
Si la excepción no se captura el flujo de ejecución se interrumpe y se muestra la información asociada a la excepción en la consola de forma que el programador pueda solucionar el problema.
Veamos un pequeño programa que lanzaría una excepción al intentar dividir 1 entre 0.
def division(a, b): return a / b def calcular(): division(1, 0) calcular()
Si lo ejecutamos obtendremos el siguiente mensaje de error:
$ python ejemplo.py
Traceback (most recent call last):
File «ejemplo.py», line 7, in
calcular()
File «ejemplo.py», line 5, in calcular
division(1, 0)
File «ejemplo.py», line 2, in division
a / b
ZeroDivisionError: integer division or modulo by zero
Lo primero que se muestra es el trazado de pila o traceback, que consiste en una lista con las llamadas que provocaron la excepción. Como vemos en el trazado de pila, el error estuvo causado por la llamada a calcular()
de la línea 7, que a su vez llama a division(1, 0)
en la línea 5 y en última instancia por la ejecución de la sentencia a / b
de la línea 2 de division
.
A continuación vemos el tipo de la excepción, ZeroDivionError
, junto a una descripción del error: «integer division or modulo by zero» (módulo o división entera entre cero).
En Python se utiliza una construcción try
–except
para capturar y tratar las excepciones. El bloque try
(intentar) define el fragmento de código en el que creemos que podría producirse una excepción. El bloque except
(excepción) permite indicar el tratamiento que se llevará a cabo de producirse dicha excepción. Muchas veces nuestro tratamiento de la excepción consistirá simplemente en imprimir un mensaje más amigable para el usuario, otras veces nos interesará registrar los errores y de vez en cuando podremos establecer una estrategia de resolución del problema.
En el siguiente ejemplo intentamos crear un objeto f
de tipo fichero. De no existir el archivo pasado como parámetro, se lanza una excepción de tipo IOError
, que capturamos gracias a nuestro try
–except
.
try: f = file("archivo.txt") except: print "El archivo no existe"
Python permite utilizar varios except
para un solo bloque try
, de forma que podamos dar un tratamiento distinto a la excepción dependiendo del tipo de excepción de la que se trate. Esto es una buena práctica, y es tan sencillo como indicar el nombre del tipo a continuación del except
.
try: num = int("3a") print no_existe except NameError: print "La variable no existe" except ValueError: print "El valor no es un numero"
Cuando se lanza una excepción en el bloque try
, se busca en cada una de las clausulas except
un manejador adecuado para el tipo de error que se produjo. En caso de que no se encuentre, se propaga la excepción.
Además podemos hacer que un mismo except
sirva para tratar más de una excepción usando una tupla para listar los tipos de error que queremos que trate el bloque:
try: num = int("3a") print no_existe except (NameError, ValueError): print "Ocurrio un error"
La construcción try
–except
puede contar además con una clausula else
, que define un fragmento de código a ejecutar sólo si no se ha producido ninguna excepción en el try
.
try: num = 33 except: print "Hubo un error!" else: print "Todo esta bien"
También existe una clausula finally
que se ejecuta siempre, se produzca o no una excepción. Esta clausula se suele utilizar, entre otras cosas, para tareas de limpieza.
try: z = x / y except ZeroDivisionError: print "Division por cero" finally: print "Limpiando..."
También es interesante comentar que como programadores podemos crear y lanzar nuestras propias excepciones. Basta crear una clase que herede de Exception
o cualquiera de sus hijas y lanzarla con raise
.
class MiError(Exception): def __init__(self, valor): self.valor = valor def __str__(self): return "Error " + str(self.valor) try: if resultado > 20: raise MiError(33) except MiError, e: print e
Por último, a continuación se listan las excepciones disponibles por defecto, así como la clase de la que deriva cada una de ellas entre paréntesis.
- BaseException: Clase de la que heredan todas las excepciones.
- Exception(BaseException): Super clase de todas las excepciones que no sean de salida.
- GeneratorExit(Exception): Se pide que se salga de un generador.
- StandarError(Exception): Clase base para todas las excepciones que no tengan que ver con salir del intérprete.
- ArithmeticError(StandardError): Clase base para los errores aritméticos.
- FloatingPointError(ArithmeticError): Error en una operación de coma flotante.
- OverflowError(ArithmeticError): Resultado demasiado grande para poder representarse.
- ZeroDivisionError(ArithmeticError): Lanzada cuando el segundo argumento de una operación de división o módulo era 0
- AssertionError(StandardError): Falló la condición de un estamento assert.
- AttributeError(StandardError): No se encontró el atributo.
- EOFError(StandardError): Se intentó leer más allá del final de fichero.
- EnvironmentError(StandardError): Clase padre de los errores relacionados con la entrada/salida.
- IOError(EnvironmentError): Error en una operación de entrada/salida.
- OSError(EnvironmentError): Error en una llamada a sistema.
- WindowsError(OSError): Error en una llamada a sistema en Windows.
- ImportError(StandardError): No se encuentra el módulo o el elemento del módulo que se quería importar.
- LookupError(StandardError): Clase padre de los errores de acceso.
- IndexError(LookupError): El índice de la secuencia está fuera del rango posible.
- KeyError(LookupError): La clave no existe.
- MemoryError(StandardError): No queda memoria suficiente.
- NameError(StandardError): No se encontró ningún elemento con ese nombre.
- UnboundLocalError(NameError): El nombre no está asociado a ninguna variable.
- ReferenceError(StandardError): El objeto no tiene ninguna referencia fuerte apuntando hacia él.
- RuntimeError(StandardError): Error en tiempo de ejecución no especificado.
- NotImplementedError(RuntimeError): Ese método o función no está implementado.
- SyntaxError(StandardError): Clase padre para los errores sintácticos.
- IndentationError(SyntaxError): Error en la indentación del archivo.
- TabError(IndentationError): Error debido a la mezcla de espacios y tabuladores.
- SystemError(StandardError): Error interno del intérprete.
- TypeError(StandardError): Tipo de argumento no apropiado.
- ValueError(StandardError): Valor del argumento no apropiado.
- UnicodeError(ValueError): Clase padre para los errores relacionados con unicode.
- UnicodeDecodeError(UnicodeError): Error de decodificación unicode.
- UnicodeEncodeError(UnicodeError): Error de codificación unicode.
- UnicodeTranslateError(UnicodeError): Error de traducción unicode.
- StopIteration(Exception): Se utiliza para indicar el final del iterador.
- Warning(Exception): Clase padre para los avisos.
- DeprecationWarning(Warning): Clase padre para avisos sobre características obsoletas.
- FutureWarning(Warning): Aviso. La semántica de la construcción cambiará en un futuro.
- ImportWarning(Warning): Aviso sobre posibles errores a la hora de importar.
- PendingDeprecationWarning(Warning): Aviso sobre características que se marcarán como obsoletas en un futuro próximo.
- RuntimeWarning(Warning): Aviso sobre comportmaientos dudosos en tiempo de ejecución.
- SyntaxWarning(Warning): Aviso sobre sintaxis dudosa.
- UnicodeWarning(Warning): Aviso sobre problemas relacionados con Unicode, sobre todo con problemas de conversión.
- UserWarning(Warning): Clase padre para avisos creados por el programador.
- KeyboardInterrupt(BaseException): El programa fué interrumpido por el usuario.
- SystemExit(BaseException): Petición del intérprete para terminar la ejecución.
Gracias por la guía, me ha servido para refrescar la memoria sobre el tema de excepciones.
Excelente este tema…sin embargo hay algo que no logro resolver..estoy utilizando excepciones para asegurarme que el usuario ingrese solamente números (ya que ocupo tranformarlos con la funcion Decimal de python) sin embargo cuando se ingresa un dato equivocado y provoco que reinicie el script, la segunda vez la excepcion no parece funcionar…alguna idea?
Hola , hace un tiempo que sigo tu sitio y siempre
me llamo la atencion tus explicaciones de python
Muy buenas tus explicaciones y ejemplos vengo repasando lo que he leido de python con ellas.
hace bastante que me intereso en python aunque
me resisto por la dificultad de utilizar interfaz
grafica en los programas .
Alguna idea de que usar ? harias ejemplos de ellas ?
mas que nada orientado a las bases de datos.
Saludos y adelante
Hay bastantes frameworks para creación de interfaces de usuario Bruno: pygtk, pyqt, wxpython, …
En principio si me gustaría tocar un poco del tema de interfaces de usuario en un futuro.
Zootropo , creo que lo ideal seria ver pygtk
aunque me cuesta bastante GTK en si , lo veo complejo , no entiendo porque no se simplifica.
Actualmente estoy programando en Harbour+OOHG
o Harbour+Minigui , son similares y muy interesantes
aunque no multiplataforma por lo menos por ahora
Estoy mirando Xharbour+xhgtk , muy interesante
y multiplataforma, esta gente ha creado unas classes
que hacen de wrapper con gtk de forma de mantener
simple el manejo de la parte grafica , con el espiritu de HMG ( minigui ) u OOHG
Hechale una mirada http://www.oohg.org
Saludos
Bruno
solo necesito un pcoco mas de clase base de excepciones
Para los que preguntais, aqui he enconetrado un manual de python con qt utilizando kdevelop designer para el entorno grafico… la verdad es que hes mas sencillo de lo que parece.
Aqui la url: http://www.lawebdelprogramador.com/cursos/enlace.php?idp=4371&id=79&texto=Python
Espero que les sirva
Pingback: Manejo de Excepciones en Python « Tutorial Python
Excelente post amigo, gracias por compartir, justo lo que buscaba.
Estas explicaciones son del libro «Python para todos», el autor es Raul Gonzales Duque, es un muy buen libro de python y es facilmente descargable.
Si te fijas en la segunda página del libro, verás que yo soy Raúl, y este es mi blog 😉
jaja Exelente ha buen post.
Muy buen artículo, felicidades.
Viendo esto he entendido, a la vez, el concepto de herencia. Cuando veía una clase con argunmentos, o sea con paréntesis, pensaba que se trataba del constructor. jajajaja
Necesito mas ejemplos acerca de excepciones y ni hablar de la secuencia Fibonacci.Saludos
Noelia.
Muy buen post para aprender sobre excepciones. Hay un detalle que cuidar. Son los ejemplos. El ultimo no esta descrito correctamente y da error NameError: name ‘resultado’ is not defined y en ningún lugar presentas que ese es el tipo de error que quieres mostrar.
Gracias por el aporte.
Pingback: Manejo de excepciones en Python | Blog de Mario Javier
Un detalle, si una excepción es manejada por un catch, el programa continúa ejecutándose de todas formas. El programa sólo deja de ejecutarse en caso de que una excepción no sea manejada. Entonces la utilidad del finally no es que un código se ejecute se produzca o no una excepción en general, pues si la excepción es manejada, el código del finally se ejecuta aún si no estuviera dentro de una finally. Entoces la verdadera utilidad del finally es que un código se ejecute aún cuando se produzca una excepción que no sea manejada, lo que no sucedería si ese código no estuviera dentro de un finally.