lundi 19 octobre 2009

Exception en Python

Mécanisme standard d'exception
Ce mécanisme n'est pas différent des autres environnements évolués. En voici la notation en Python.
try:
    try:
            # Création d'une exception !
            4/0
    except:
            print('except')
            raise
finally:
    print( 'finally' )

# ou encore
try:
  4/0
except:
  print('except')
  raise
finally:
  print( 'finally' )
Résultat:
except
finally
Traceback (most recent call last):
File "<stdin>", line 3, in <module>
ZeroDivisionError: integer division or modulo by zero
Créer une classe d'exception
Python requière l'usage de classes dans les mécanismes d'exception. Cette dernière servira à l'identification du type d'exception ainsi qu'au transport des arguments/details de l'exception. Bien que toutes les classes soient acceptées,il est préférable d'utiliser un descendant d'Exception... cela permet de faire un casting d'erreur efficace. Encore une fois, rien de différent par rapport aux autres langages évolués.
class myError(Exception):
    pass

def doAnError():
    raise myError()

doAnError()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in doAnError
__main__.myError: <__main__.myError instance at 0xb7d0804c>

Casting d'exception
Le casting d'exception s'obtient en placant la classe après le mot clé "except". Dans ce cas, seule les exceptions de ce type (et dérivés) seront interceptées.
try:
  8/0
except ArithmeticError:
  print( 'Oups!' )

Il est également possible de récupérer une référence vers l'objet d'exception en déclarant un second paramètre après le mot clé except.
class anError( Exception ):
    pass

try:
    raise anError()
except Exception, errObj:
    print( id(errObj) )
    dir( errObj )
    print( errObj )
    print( '--- End of Exception ---' )
Resultat:
3080090404
['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__getitem__', '__getslice__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__str__', '__weakref__', 'args', 'message']

--- End of Exception ---

Classes d'exception de base
Exception
Classe de base de toutes les exceptions. Le constructeur prend en plusieurs paramètres qui sont stockés dans l'attribut args. Lors de l'affichage par l'interpreteur, le function __str__() est appelée pour afficher les informations de l'exception. Dans le cas de Exception, __str__() affiche le contenu de l'attribut args.

StandardError
class StandardError( Exception )
Classe de base de presque toutes les exceptions en Python.

ArithmeticError
class ArithmeticError( StandardError )
Pour toutes les erreurs. On retrouve en descendant ZeroDivisionError, OverflowError (dépassement de capacité), FloatingPointError (erreur en calcul flottant)

LookupError
class LookupError( StandardError )
Utilisé lors de l'utilisation d'un index est incorrect sur une liste ou lors de l'utilisation d'une clé incorrecte dans un mapping.

EnvironmentError
class EnvironmentError( StandardError )
Utilisé comme classe de base pour les erreurs de type système (lecture fichier, appel API, etc).
Ce type d'erreur accepte un "Numéro d'erreur" et un message (les No d'erreur étant très courant en programmation système).
Voir attibut "errno".
Parmis les descendant, l'on retrouve IOError et OSError

ValueError
Class ValueError( StandardError )
Utiliser pour indiqué une valeur d'argument inappropriée (de type incorrecte).

UnicodeError
class UnicodeError( ValueError )
Classe de base pour les erreur de conversion unicode.
Parmis les descendant l'on retrouve UnicodeEncodeError, UnicodeDecodeError.

AttributeError
class AttributeError( StandardError )
Indique un attribut manquant.

NameError
class NameError( StandardError )
Indique un nom qui, globalement, ne peut pas être résolu.

Notes en vrac
Passage d'arguments à la classe d'Exception
def doSomeStuffWithError():
    try:
            4/0
    except:
            raise Exception('Un message d\'erreur', 'un brol', -12 )

doSomeStuffWithError()
print( '-----------------------' )
try:
    doSomeStuffWithError()
except Exception, errObj:
    print( errObj.args ) 
avec pour résultat:
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in doSomeStuffWithError
Exception: ("Un message d'erreur", 'un brol', -12)
-----------------------
("Un message d'erreur", 'un brol', -12)


Casting multiples
try:
  doStuffWithError()
except ArithmeticError:
  print( 'Damned!! A math error!' )
# Matching a list of exception class
except (AttributeError, IOError ):
  print( 'Oups!' )

Aucun commentaire: