ajout de la doc sur les exceptions
This commit is contained in:
parent
78acdb5816
commit
7b99d805c6
246
python/formation/exceptions.txt
Normal file
246
python/formation/exceptions.txt
Normal file
@ -0,0 +1,246 @@
|
|||||||
|
.. default-role:: literal
|
||||||
|
|
||||||
|
Le style de programmation par exceptions
|
||||||
|
========================================
|
||||||
|
|
||||||
|
.. glossary::
|
||||||
|
|
||||||
|
Exception
|
||||||
|
|
||||||
|
Les exceptions permettent de récupérer des situations où le calcul ne peut pas se poursuivre.
|
||||||
|
Dans ces cas, un récupérateur d'exceptions permet de continuer le calcul
|
||||||
|
sachant qu'une des branches a échoué.
|
||||||
|
|
||||||
|
|
||||||
|
Exemple d':term:`exception`
|
||||||
|
|
||||||
|
>>> assert 2 == 1
|
||||||
|
Traceback (most recent call last):
|
||||||
|
File "<stdin>", line 1, in <module>
|
||||||
|
AssertionError
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
La règle du samouraï
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
.. important:: règle du Samouraï : une fonction doit renvoyer le résultat escompté
|
||||||
|
ou bien lever une exception
|
||||||
|
|
||||||
|
|
||||||
|
>>> def function_raise(x):
|
||||||
|
... if not type(x) == int:
|
||||||
|
... raise TypeError("Pas le bon type")
|
||||||
|
... else:
|
||||||
|
... return x + 1
|
||||||
|
...
|
||||||
|
>>> try:
|
||||||
|
... e = function_raise("une string")
|
||||||
|
... except TypeError, e:
|
||||||
|
... print e
|
||||||
|
...
|
||||||
|
Pas le bon type
|
||||||
|
>>
|
||||||
|
|
||||||
|
- la fonction doit renvoyer des valeurs du même type (ou bien ``None``)
|
||||||
|
- la fonction doit lever une exception appropriée
|
||||||
|
|
||||||
|
|
||||||
|
utiliser la pile d'appel pour débugger
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
|
Utiliser la pile d'appels, elle se lit de bas en haut. Il est possible de
|
||||||
|
provoquer cette pile d'appels.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
|
.. todo:: s'exercer à lire une pile d'appels un peu complexe.
|
||||||
|
|
||||||
|
|
||||||
|
Traiter une exception avec
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
try:
|
||||||
|
...
|
||||||
|
except:
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
|
else:
|
||||||
|
bla bla
|
||||||
|
finally:
|
||||||
|
bla bla
|
||||||
|
|
||||||
|
.. attention:: ne **jamais** briser la pile d'appels sans savoir précisément
|
||||||
|
ce que l'on fait, et remonter une autre exception
|
||||||
|
|
||||||
|
Exemple :
|
||||||
|
|
||||||
|
|
||||||
|
>>> def function(x):
|
||||||
|
... if x == 1: raise TypeError("pas le bon type")
|
||||||
|
... else: return "ok"
|
||||||
|
...
|
||||||
|
>>> def function2(x):
|
||||||
|
... try:
|
||||||
|
... return "c'est " + function(x)
|
||||||
|
... except TypeError, e:
|
||||||
|
... raise AssertionError("on a une autre exception là")
|
||||||
|
...
|
||||||
|
>>> try:
|
||||||
|
... function2(1)
|
||||||
|
... except Exception, e:
|
||||||
|
... print e
|
||||||
|
...
|
||||||
|
on a une autre exception là
|
||||||
|
>>>
|
||||||
|
|
||||||
|
Le raise (ou le re-raise) est souvent utilisé pour lever une exception métier
|
||||||
|
et cacher une exception système de bas niveau.
|
||||||
|
|
||||||
|
exemple::
|
||||||
|
|
||||||
|
try:
|
||||||
|
add_s(dn, listdata)
|
||||||
|
except ldap.LDAPError, err:
|
||||||
|
raise MyOwnError(msg + str(err))
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
.. todo:: dans quel cas entrons-nous dans le `else` ? dans le `finally` ?
|
||||||
|
|
||||||
|
.. todo:: créer des exceptions métier
|
||||||
|
|
||||||
|
exemple d'exceptions *dans la vraie vie*::
|
||||||
|
|
||||||
|
"user defined exceptions"
|
||||||
|
|
||||||
|
|
||||||
|
# Exceptions for an Option
|
||||||
|
class PropertiesOptionError(AttributeError):
|
||||||
|
"attempt to access to an option with a property that is not allowed"
|
||||||
|
def __init__(self, msg, proptype):
|
||||||
|
self.proptype = proptype
|
||||||
|
super(PropertiesOptionError, self).__init__(msg)
|
||||||
|
|
||||||
|
|
||||||
|
#____________________________________________________________
|
||||||
|
# Exceptions for a Config
|
||||||
|
class ConfigError(Exception):
|
||||||
|
"""attempt to change an option's owner without a value
|
||||||
|
or in case of `_cfgimpl_descr` is None
|
||||||
|
or if a calculation cannot be carried out"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ContextError(Exception):
|
||||||
|
"""context needed but not given
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ConflictError(Exception):
|
||||||
|
"duplicate options are present in a single config"
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
#____________________________________________________________
|
||||||
|
# miscellaneous exceptions
|
||||||
|
class RequirementError(Exception):
|
||||||
|
"""a recursive loop occurs in the requirements tree
|
||||||
|
requires
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class SlaveError(Exception):
|
||||||
|
"problem with a slave's value length"
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ConstError(TypeError):
|
||||||
|
"no uniq value in _NameSpace"
|
||||||
|
pass
|
||||||
|
|
||||||
|
Créer le plus possible ses propres exceptions spécifiques au programme
|
||||||
|
La programmation par exception peut vite devenir un style de programmation
|
||||||
|
très utilisé. C'est assez agréable mais le réserver pour la gestion d'une situation
|
||||||
|
particulière, que ça reste une intervention pour les cas non gérés par le programme
|
||||||
|
(en général).
|
||||||
|
|
||||||
|
Les exceptions imbriquées
|
||||||
|
--------------------------------
|
||||||
|
|
||||||
|
>>> try:
|
||||||
|
... ma_func()
|
||||||
|
... except TypeError, e:
|
||||||
|
... do_something()
|
||||||
|
... except Exception, e:
|
||||||
|
... do_somethin_else()
|
||||||
|
...
|
||||||
|
|
||||||
|
Exemple de programme utilisant massivement la programmation par exceptions :
|
||||||
|
`tiramisu`_
|
||||||
|
|
||||||
|
.. _tiramisu: http://tiramisu.labs.libre-entreprise.org/
|
||||||
|
|
||||||
|
|
||||||
|
La hiérarchie des exceptions
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Extrait de la documentation officielle::
|
||||||
|
|
||||||
|
BaseException
|
||||||
|
+-- SystemExit
|
||||||
|
+-- KeyboardInterrupt
|
||||||
|
+-- GeneratorExit
|
||||||
|
+-- Exception
|
||||||
|
+-- StopIteration
|
||||||
|
+-- StandardError
|
||||||
|
| +-- BufferError
|
||||||
|
| +-- ArithmeticError
|
||||||
|
| | +-- FloatingPointError
|
||||||
|
| | +-- OverflowError
|
||||||
|
| | +-- ZeroDivisionError
|
||||||
|
| +-- AssertionError
|
||||||
|
| +-- AttributeError
|
||||||
|
| +-- EnvironmentError
|
||||||
|
| | +-- IOError
|
||||||
|
| | +-- OSError
|
||||||
|
| | +-- WindowsError (Windows)
|
||||||
|
| | +-- VMSError (VMS)
|
||||||
|
| +-- EOFError
|
||||||
|
| +-- ImportError
|
||||||
|
| +-- LookupError
|
||||||
|
| | +-- IndexError
|
||||||
|
| | +-- KeyError
|
||||||
|
| +-- MemoryError
|
||||||
|
| +-- NameError
|
||||||
|
| | +-- UnboundLocalError
|
||||||
|
| +-- ReferenceError
|
||||||
|
| +-- RuntimeError
|
||||||
|
| | +-- NotImplementedError
|
||||||
|
| +-- SyntaxError
|
||||||
|
| | +-- IndentationError
|
||||||
|
| | +-- TabError
|
||||||
|
| +-- SystemError
|
||||||
|
| +-- TypeError
|
||||||
|
| +-- ValueError
|
||||||
|
| +-- UnicodeError
|
||||||
|
| +-- UnicodeDecodeError
|
||||||
|
| +-- UnicodeEncodeError
|
||||||
|
| +-- UnicodeTranslateError
|
||||||
|
+-- Warning
|
||||||
|
+-- DeprecationWarning
|
||||||
|
+-- PendingDeprecationWarning
|
||||||
|
+-- RuntimeWarning
|
||||||
|
+-- SyntaxWarning
|
||||||
|
+-- UserWarning
|
||||||
|
+-- FutureWarning
|
||||||
|
+-- ImportWarning
|
||||||
|
+-- UnicodeWarning
|
||||||
|
+-- BytesWarning
|
@ -1,5 +1,7 @@
|
|||||||
Liste des exercices
|
Liste des exercices
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
.. todolist::
|
Voici la liste des liens vers les différents exercices de la formation.
|
||||||
|
|
||||||
|
|
||||||
|
.. todolist::
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
apprentissage de la programmation avec python
|
Apprentissage de la programmation avec python
|
||||||
----------------------------------------------
|
----------------------------------------------
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
@ -12,20 +12,29 @@ apprentissage de la programmation avec python
|
|||||||
testsunitaires
|
testsunitaires
|
||||||
|
|
||||||
|
|
||||||
programmation python, connaissances de base
|
Programmation python, connaissances de base
|
||||||
--------------------------------------------
|
--------------------------------------------
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 1
|
:maxdepth: 1
|
||||||
|
|
||||||
classes
|
classes
|
||||||
prompt
|
prompt
|
||||||
specialmethods
|
specialmethods
|
||||||
|
exceptions
|
||||||
stdlib
|
stdlib
|
||||||
|
|
||||||
|
Récapitulatifs de la formation
|
||||||
|
---------------------------------
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 1
|
||||||
|
|
||||||
|
exercices
|
||||||
|
|
||||||
Index et recherche
|
Index et recherche
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
* :doc:`exercices`
|
|
||||||
* :ref:`genindex`
|
* :ref:`genindex`
|
||||||
* :ref:`modindex`
|
* :ref:`modindex`
|
||||||
* :ref:`search`
|
* :ref:`search`
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
.. default-role:: literal
|
||||||
|
|
||||||
Structures de contrôle et fonctions
|
Structures de contrôle et fonctions
|
||||||
====================================
|
====================================
|
||||||
|
|
||||||
@ -189,7 +191,6 @@ les expressions générateurs
|
|||||||
18
|
18
|
||||||
>>>
|
>>>
|
||||||
|
|
||||||
|
|
||||||
le polymorphisme paramétrique
|
le polymorphisme paramétrique
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
@ -202,23 +203,3 @@ la fonction print
|
|||||||
1
|
1
|
||||||
|
|
||||||
.. todo:: `print 1` et `print "1"` renvoient le même résultat. Pourquoi ?
|
.. todo:: `print 1` et `print "1"` renvoient le même résultat. Pourquoi ?
|
||||||
|
|
||||||
la programmation par exceptions
|
|
||||||
-------------------------------------
|
|
||||||
|
|
||||||
>>> def function_raise(x):
|
|
||||||
... if not type(x) == int:
|
|
||||||
... raise TypeError("Pas le bon type")
|
|
||||||
... else:
|
|
||||||
... return x + 1
|
|
||||||
...
|
|
||||||
>>> try:
|
|
||||||
... e = function_raise("une string")
|
|
||||||
... except TypeError, e:
|
|
||||||
... print e
|
|
||||||
...
|
|
||||||
Pas le bon type
|
|
||||||
>>
|
|
||||||
|
|
||||||
.. important:: règle du Samouraï : une fonction doit renvoyer le résultat escompté
|
|
||||||
ou bien lever une exception
|
|
||||||
|
@ -19,7 +19,7 @@ les types de tests :
|
|||||||
|
|
||||||
Quel outil utiliser ?
|
Quel outil utiliser ?
|
||||||
|
|
||||||
- la :doc:`stdlib` propose le module :mod:`unittest`
|
- la :doc:`stdlib` propose le module :mod:`unittest` et unittest2.
|
||||||
|
|
||||||
.. module:: py.test
|
.. module:: py.test
|
||||||
:synopsis: outil de test unitaires de la pylib
|
:synopsis: outil de test unitaires de la pylib
|
||||||
@ -66,37 +66,6 @@ options utiles dans `py.test`
|
|||||||
|
|
||||||
py.test -k test_simple
|
py.test -k test_simple
|
||||||
|
|
||||||
|
|
||||||
utiliser la pile d'appel pour débugger
|
|
||||||
---------------------------------------
|
|
||||||
|
|
||||||
utiliser la pile d'appels, elle se lit de bas en haut. Il est possible de
|
|
||||||
provoquer cette pile d'appels.
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
import traceback
|
|
||||||
traceback.print_exc()
|
|
||||||
|
|
||||||
|
|
||||||
traiter une exception avec
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
try:
|
|
||||||
...
|
|
||||||
except:
|
|
||||||
import traceback
|
|
||||||
traceback.print_exc()
|
|
||||||
|
|
||||||
else:
|
|
||||||
bla bla
|
|
||||||
finally:
|
|
||||||
bla bla
|
|
||||||
|
|
||||||
|
|
||||||
créer le plus possible ses propres exceptions spécifiques au programme
|
|
||||||
|
|
||||||
utiliser le module :mod:`pdb`
|
utiliser le module :mod:`pdb`
|
||||||
|
|
||||||
.. module:: pdb
|
.. module:: pdb
|
||||||
|
Loading…
Reference in New Issue
Block a user