Hasta ahora no hab�amos m�s que mencionado los mensajes de error, pero si has probado los ejemplos puede que hayas visto algunos. Hay (al menos) dos tipos de errores diferenciables: los errores de sintaxis y las excepciones.
Los errores de sintaxis son la clase de queja m�s com�n del int�rprete cuando todav�a est�s aprendiendo Python:
>>> while 1 print 'Hola mundo' File "<stdin>", line 1 while 1 print 'Hola mundo' ^ SyntaxError: invalid syntax
El int�rprete sint�ctico repite la l�nea ofensiva y presenta una `flechita' que apunta al primer punto en que se ha detectado el error. La causa del error est� (o al menos se ha detectado) en el s�mbolo anterior a la flecha: En este ejemplo, el error se detecta en la palabra clave print, porque faltan los dos puntos (":") antes de �sta. Se muestran el nombre del fichero y el n�mero de l�nea para que sepas d�nde buscar, si la entrada ven�a de un fichero.
Aun cuando una sentencia o expresi�n sea sint�cticamente correcta, puede causar un error al intentar ejecutarla. Los errores que se detectan en la ejecuci�n se llaman excepciones y no son mortales de necesidad, pronto va a aprender a gestionarlos desde programas en Python. Las excepciones no capturadas causan mensajes de error como el siguiente:
>>> 10 * (1/0) Traceback (innermost last): File "<stdin>", line 1 ZeroDivisionError: integer division or modulo >>> 4 + fiambre*3 Traceback (innermost last): File "<stdin>", line 1 NameError: fiambre >>> '2' + 2 Traceback (innermost last): File "<stdin>", line 1 TypeError: illegal argument type for built-in operation
La �ltima l�nea del mensaje de error indica qu� ha pasado. Las excepciones pueden ser de diversos tipos, que se presentan como parte del mensaje: los tipos del ejemplo son ZeroDivisionError, NameError y TypeError. La cadena presentada como tipo de excepci�n es el nombre interno de la excepci�n que ha ocurrido. Esto es aplicable a todas las excepciones internas, pero no es necesariamente cierto para las excepciones definidas por el usuario (sin embargo, es una �til convenci�n). Los nombres de excepciones est�ndar son identificadores internos (no palabras reservadas).
El resto de la l�nea contiene detalles cuya interpretaci�n depende del tipo de excepci�n.
La parte anterior al mensaje de error muestra el contexto donde ocurri� la excepci�n, en forma de trazado de la pila. En general, contiene un trazado que muestra las l�neas de c�digo fuente, aunque no mostrar� las l�neas le�das de la entrada est�ndar.
La Referencia de las bibliotecas enumera las excepciones internas y sus respectivos significados.
Es posible escribir programas que gestionen ciertas excepciones. Mira el siguiente ejemplo, que pide datos al usuario hasta que se introduce un entero v�lido, pero permite al usuario interrumpir la ejecuci�n del programa (con Control-C u otra adecuada para el sistema operativo en cuestion); Observa que una interrupci�n generada por el usuario se se�aliza haciendo saltar la excepcion KeyboardInterrupt.
>>> while 1: ... try: ... x = int(raw_input("Introduce un n�mero: ")) ... break ... except ValueError: ... print "�Huy! No es un n�mero. Prueba de nuevo..." ...
La sentencia try funciona de la siguiente manera:
Una sentencia try puede contener m�s de una cl�usula except, para capturar diferentes excepciones. Nunca se ejecuta m�s de un gestor para una sola excepci�n. Los gestores s�lo capturan excepciones que saltan en la cl�usula try correspondiente, no en otros gestores de la misma sentencia try. Una cl�usula try puede capturar m�s de una excepci�n, nombr�ndolas dentro de una lista:
... except (RuntimeError, TypeError, NameError): ... pass
La �ltima cl�usula except puede no nombrar ninguna excepci�n, en cuyo caso hace de comod�n y captura cualquier excepci�n. Se debe utilizar esto con mucha precauci�n, pues es muy f�cil enmascarar un error de programaci�n real de este modo. Tambi�n se puede utilizar para mostrar un mensaje de error y relanzar la excepci�n (permitiendo de este modo que uno de los llamantes gestione la excepci�n a su vez):
import string, sys try: f = open('mifichero.txt') s = f.readline() i = int(string.strip(s)) except IOError, (errno, strerror): print "Error de E/S(%s): %s" % (errno, strerror) except ValueError: print "No ha sido posible covertir los datos a entero." except: print "Error no contemplado:", sys.exc_info()[0] raise
La sentencia try ... except tiene una cl�usula else opcional, que aparece tras las cl�usulas except. Se utiliza para colocar c�digo que se ejecuta si la cl�usula try no hace saltar ninguna excepci�n. Por ejemplo:
for arg in sys.argv[1:]: try: f = open(arg, 'r') except IOError: print 'no se puede abrir', arg else: print arg, 'contiene', len(f.readlines()), 'l�neas' f.close()
El uso de la cl�usula else es mejor que a�adir c�digo adicional a la cl�usula try porque evita que se capture accidentalemente una excepci�n que no fue lanzada por el c�digo protegido por la sentencia try ... except.
Cuando salta una excepci�n, puede tener un valor asociado, tambi�n conocido como el/los argumento/s de la excepci�n. Que el argumento aparezca o no y su tipo dependen del tipo de excepci�n. En los tipos de excepci�n que tienen argumento, la cl�usula except puede especificar una variable tras el nombre de la excepci�n (o tras la lista) que recibir� el valor del argumento, del siguiente modo:
>>> try: ... fiambre() ... except NameError, x: ... print 'nombre', x, 'sin definir' ... nombre fiambre sin definir
Si una excepci�n no capturada tiene argumento, se muestra como �ltima parte (detalle) del mensaje de error.
Los gestores de excepciones no las gestionan s�lo si saltan inmediatamente en la cl�usula try, tambi�n si saltan en funciones llamadas (directa o indirectamente) dentro de la cl�usula try. Por ejemplo:
>>> def esto_casca(): ... x = 1/0 ... >>> try: ... esto_casca() ... except ZeroDivisionError, detalle: ... print 'Gesti�n de errores:', detalle ... Gesti�n de errores: integer division or modulo
La sentencia raise (hacer saltar) permite que el programador fuerce la aparici�n de una excepci�n. Por ejemplo:
>>> raise NameError, 'MuyBuenas' Traceback (innermost last): File "<stdin>", line 1 NameError: MuyBuenas
El primer argumento para raise indica la excepci�n que debe saltar. El segundo argumento, opcional, especifica el argumento de la excepci�n.
Los programas pueden nombrar sus propias excepciones asignando una cadena a una variable o creando una nueva clase de excepci�n. Por ejemplo:
>>> class MiError: ... def __init__(self, valor): ... self.valor = valor ... def __str__(self): ... return `self.valor` ... >>> try: ... raise raise MiError(2*2) ... except MiError, e: ... print 'Ha saltado mi excepci�n, valor:', e.valor ... Ha saltado mi excepci�n, valor: 4 >>> raise mi_exc, 1 Traceback (innermost last): File "<stdin>", line 1 mi_exc: 1
Muchos m�dulos est�ndar utilizan esto para informar de errores que pueden ocurrir dentro de las funciones que definen.
Hay m�s informaci�n sobre las clases en el cap�tulo
La sentencia try tiene otra cl�usula opcional cuya intenci�n es definir acciones de limpieza que se han de ejecutar en cualquier circunstancia. Por ejemplo:
>>> try: ... raise KeyboardInterrupt ... finally: ... print '�Adi�s, mundo cruel!' ... �Adi�s, mundo cruel! Traceback (innermost last): File "<stdin>", line 2 KeyboardInterrupt
La cl�usula finally (finalmente) se ejecuta tanto si ha saltado una excepci�n dentro de la cl�usula try como si no. Si ocurre una excepci�n, vuelve a saltar tras la ejecuci�n de la cl�usula finally. Tambi�n se ejecuta la cl�usula finally ``a la salida'' si se abandona la sentencia try mediante break o return.
Una sentencia try debe tener una o m�s cl�usulas except o una cl�usula finally, pero no las dos.