ajout de la doc sur les exceptions

This commit is contained in:
gwen 2015-05-04 15:38:51 +02:00 committed by Benjamin Bohard
parent 78acdb5816
commit 7b99d805c6
5 changed files with 264 additions and 57 deletions

View 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

View File

@ -1,5 +1,7 @@
Liste des exercices
--------------------
.. todolist::
Voici la liste des liens vers les différents exercices de la formation.
.. todolist::

View File

@ -1,5 +1,5 @@
apprentissage de la programmation avec python
Apprentissage de la programmation avec python
----------------------------------------------
.. toctree::
@ -12,20 +12,29 @@ apprentissage de la programmation avec python
testsunitaires
programmation python, connaissances de base
Programmation python, connaissances de base
--------------------------------------------
.. toctree::
:maxdepth: 1
classes
prompt
specialmethods
exceptions
stdlib
Récapitulatifs de la formation
---------------------------------
.. toctree::
:maxdepth: 1
exercices
Index et recherche
-------------------
* :doc:`exercices`
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

View File

@ -1,3 +1,5 @@
.. default-role:: literal
Structures de contrôle et fonctions
====================================
@ -189,7 +191,6 @@ les expressions générateurs
18
>>>
le polymorphisme paramétrique
-----------------------------
@ -202,23 +203,3 @@ la fonction print
1
.. 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

View File

@ -19,7 +19,7 @@ les types de tests :
Quel outil utiliser ?
- la :doc:`stdlib` propose le module :mod:`unittest`
- la :doc:`stdlib` propose le module :mod:`unittest` et unittest2.
.. module:: py.test
:synopsis: outil de test unitaires de la pylib
@ -66,37 +66,6 @@ options utiles dans `py.test`
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`
.. module:: pdb