Mis a jour le 2025-04-14, 12:10

Exceptions

Syntaxe des exceptions :
while 1:
    try:
        x = int(raw_input('number:'))
        break
    except ValueError:
        print('try again')
  
Une clause except peut avoir plusieurs exceptions :
  • séquentiellement (mais seul le premier qui matche sera exécuté, même si plusieurs matchent) :
    try:
        f = open('toto')
        s = f.readline()
        i = int(string.strip(s))
    except IOError:
        print('I/O error')
    except ValueError:
        print('could not convert')
    except: # all other exceptions
        print('unexpected')
        raise # reraise exception after message printing
    else: # done if no exception raised
        f.close()
      
  • except sans type d'exception catche tous les types.
  • raise tout seul dans un except : lève à nouveau la même exception.
  • ou récupération de différents types d'exception en même temps :
    try:
        ...
    except (RuntimeError, TypeError, NameError):
        ...
        
Les exceptions sont des classes :
  • elles dérivent toutes de la classe BaseException, mais si on veut créer ses propres classes d'exception, les faire dériver de la classe Exception, plutôt que BaseException (voir ci-dessous).
  • lors de l'appel à sys.exit(), une exception SystemExit est levée. SystemExit dérive directement de BaseException, donc si on catche BaseException, on va aussi la catcher !
  • lors d'un Ctrl-C, une exception KeyboardInterrupt est levée. KeyboardInterrupt dérive aussi directement de BaseException, donc si on catche BaseException, on va aussi la catcher !
  • on peut définir ses propres classes d'exception en les faisant dériver de la classe Exception (éviter de les faire dériver de BaseException).
  • on peut catcher toutes les exceptions "normales" et examiner leur type ou le message associé :
    try:
        x = 'a' + 8
    except Exception as e:
        print(type(e))
        print(str(e))
        
  • StandardError est une exception dérivée de Exception et de laquelle la plupart des exceptions dérivent (notamment RuntimeError, KeyError, ...)
On peut exécuter du code si aucune exception levée :
try:
    ...
except TypeError:
    ...
else:
    print('Aucune exception n'a eu lieu')
  
Certaines exceptions ont des arguments que l'on peut alors récupérer :
except NameError as e: # un argument, e, contenant les arguments de l'exception.
    print(arg:', e)
  
Les exceptions non traitées remontent d'appel en appel.
Pour catcher toutes les exceptions en récupérant leur message :
try:
    ...
except Exception as e:
   print(str(e))
   ...
  
Levée d'exception explicite :
  • raise NameError('badName') ou aussi raise NameError, 'badName' : lève une exception NameError avec un argument.
  • on peut lever une exception avec plusieurs arguments de types quelconques (récupérables sous forme de tuple) : raise Exception(arg1, arg2)
  • on peut alors récupérer ces arguments en faisant :
    except Exception as e:
      print(e.args)
        
finally : code toujours executé, qu'il y ait eu levée d'exception ou non :
try:
    1 / 0
except TypeError:
    print('type error')
finally: # toujours exécuté, avant de lever l'exception
    print('always done')
  
Traceback : permet de voir la pile des appels lors d'une erreur :
  • faire import traceback.
  • traceback.print_exc() : imprime sur stderr la pile des appels de la dernière exception.
  • traceback.format_exc() : permet de récupérer la pile des appels sous forme de chaîne de caractères.
Pour avoir la pile des appels :
  • import inspect; stack = inspect.stack() : renvoie une liste avec un élément par élément de la pile avec le premier élément étant l'appel à cette fonction stack()
  • pour avoir le nom de la fonction appelante la fonction contenant cet ordre : stack[1][3]
  • pour avoir la ligne ou la fonction est appelée : stack[1][2]
Pour avoir la liste des numéros de lignes après une exception :
info = sys.exc_info()[2]
while True:
  print(str(info.tb_lineno)+ ' at ' + info.tb_frame.f_code.co_filename)
  info = info.tb_next
  if info is None:
    break
  
Assertions en python :
  • assert x == 2 : vérifie si la condition est vraie, et si non, lance une exception AssertionError.
  • assert x == 2, 'x ne valait pas 2' : idem, mais en plus, affiche le message d'erreur indiqué.
  • les assertions sont vérifiées, sauf si on fournit à python l'option -O est fournie (python -O ...)

Copyright python-simple.com
programmer en python, tutoriel python, graphes en python, Aymeric Duclert