Les exceptions sont un mécanisme de gestion d'erreurs très performant:
Exemple:
try: print "Hello world" except: print "Si print Hello world echoue ce texte sera affiché" else: print "Ce message ne s'affiche que si le try a réussi" finally: print "Quoi qu'il arrive ce texte sera affiché"
Seul try et except sont obligatoires.
Pour les versions antérieurs à Python 2.5, les clauses except et finally sont mutuellement exclusives. Pour ces versions, il est possible d'imbriquer un bloc try/except dans un bloc try/finally:
try: try: raise RuntimeError("test") except RuntimeError, e: print "oops, erreur : %s" % e finally: print "on passe ici de toutes façons"
Il est également possible d'intercepter une erreur comme ceci :
try: print 5 / 0 except Exception, err: # on récupère n'importe qu'elle erreur que l'on peut traiter (log, message...) print err
Précaution d'emploi
Utiliser une clause except sans préciser la (ou les) exceptions attendues est une très mauvaise pratique: cela peut masquer des exceptions inattendues, et rendre le débogage difficile (expérience vécue...). Noter aussi que SystemExit (générée par sys.exit()) est une exception, et qu'on n'a pas forcément envie de la 'masquer' par inadvertance...
Tester l'ouverture d'un fichier
try: file = open("84.txt", 'r') except IOError: print "Impossible d'ouvrir le fichier" except: print "autre erreur"
Tester si une variable existe
try: print sys.argv[1] except NameError: print "Pas d'argument donné au programme"
Ou, plus généralement:
try: ma_variable except NameError: print "ma_variable n'existe pas" else: print "ma_variable existe : %s" % ma_variable
Intercepter toutes les erreurs
On peut désirer intercepter toutes les erreurs pour un traitement particulier (un fichier log, un envoi d'email au développeur, un affichage dans une interface graphique...).
import traceback def Myexcepthook(type, value, tb): print "in Myexcepthook" lines=traceback.format_exception(type, value, tb) print "---------------------Traceback lines-----------------------" print "\n".join(lines) print "-----------------------------------------------------------" sys.exit(2) sys.excepthook=Myexcepthook
Maintenant, toutes les exceptions passent par la fonction Myexcepthook. Il suffit de l'adapter à ses besoins.
Autre exemple sans toucher au gestionnaire d'exception général:
import traceback def cinquieme(a): return 5/a def mafonction(valeur): b = cinquieme(valeur) * 100 try: print mafonction(0) except Exception, ex: logfile = open('monlog.log','a') traceback.print_exc(file=logfile) logfile.close() print "Oups ! Problème. Merci de regarder le fichier de log."
Et on peut voir dans le fichier monlog.log:
Traceback (most recent call last): File "monprogramme.py", line 13, in ? print mafonction(0) File "monprogramme.py", line 10, in mafonction b = cinquieme(valeur) * 100 File "monprogramme.py", line 7, in cinquieme return 5/a ZeroDivisionError: integer division or modulo by zero