diff --git a/sessions/python-10.md b/sessions/python-10.md index c0bfc88..d2efa86 100644 --- a/sessions/python-10.md +++ b/sessions/python-10.md @@ -5,16 +5,7 @@ \center \huge Exceptions -# Examples d'erreurs - - * division par zéro - * dépassement d'un tableau - * clé non trouvée dans un dico - * opération entre types incompatibles - * le fichier n'existe pas - * la variable n'existe pas - -# Les backtraces +# Exemple ```python def une_fonction(): @@ -39,8 +30,9 @@ Traceback (most recent call last): ZeroDivisionError: division by zero ``` +ZeroDivisionError est une *classe*. -# Les backtraces +# Exemple modifié ```python def une_fonction(diviseur): @@ -52,7 +44,8 @@ def une_autre_fonction(): une_autre_fonction() ``` -# Les backtraces +# Exemple modifié + ``` Traceback (most recent call last): @@ -65,16 +58,49 @@ Traceback (most recent call last): ZeroDivisionError: division by zero ``` -# Lever une exception +**Prenez le temps de lire les backtraces soigneusement!** -```python -def retirer_somme(compte, montant): - solde = ... - if montant >= solde: - raise ValueError("montant supérieur au solde!") +# Exemples d'erreurs + + * `b += 2` - **NameError** + * `a / 9` - **ZeroDivisionError** + * `my_list[42]` - **IndexError** + * ``my_dict["bad-key"]`` - **KeyError** + * `1 + "two"` - **TypeError** + * `open("badpath")` - **FileNotFoundError** + +# Hiérarchie d'exceptions (simplifiée) + +``` +BaseException + +-- SystemExit + +-- KeyboardInterrupt + +-- Exception + +-- ArithmeticError + | +-- ZeroDivisionError + +-- LookupError + | +-- IndexError + | +-- KeyError + +-- OSError + | +-- FileNotFoundError + +-- TypeError + +-- ValueError + ``` +Liste complète dans la documentation: +https://docs.python.org/fr/3/library/exceptions.html#exception-hierarchy + +# KeyboardInterrupt et SystemExit + +* `KeyboardInterrupt` est levée quand on fait `ctrl-c`. + +* `SystemExit` est levé quand on utilise `sys.exit()` + * Python cache la backtrace dans ce cas-là + * Pas utile de l'attrapper en général + + # Attraper une exception ```python @@ -85,16 +111,11 @@ except ZeroDivisionError: print("someone tried to divide by zero!") ``` -* Note: si l'exception n'est pas une fille de la classe attrapee, c'est rate. - -# Attraper une exception - -* On peut mettre plusieurs blocs de `except` -* On peut attraper plusieurs exceptions d'un coup - +* Note: si l'exception n'est pas une fille de la classe attrapée, c'est raté. # Attraper une exception +On peut mettre plusieurs blocs de `except` ```python try: @@ -105,43 +126,71 @@ except FileNotFoundError: print("file not found") ``` +# Attraper une exception +On peut attraper plusieurs exceptions d'un coup -Attention aux bare except - -# Hiérarchies - -À connaître -À utiliser si vous faites une librairie. +```python +try: + something_dangerous() +except (ZeroDivisionError, FileNotFoundError): + print("something bad happened") +``` # finally, else -# WBYL et EAFP -Watch Before You Leap -Easier to Ask for Forgiveness than Permission +```python +try: + something_dangerous() +except SomeError: + print("something bad happened") +else: + print("everything went well") +finally: + clean_up() +``` + +# WBYL -fichiers encore: +* Watch Before You Leap ```python if exists(): -if pas_un_dossier(): -if j_ai_les_droits_en_lecture(): -open(filename): + if pas_un_dossier(): + if j_ai_les_droits_en_lecture(): + open(filename): ``` +# EAFP + +* Easier to Ask for Forgiveness than Permission + ```python try: - open(filename): + file = open(filename) catch IOError: ... +finally: + file.close() ``` +# Avec with + +Pas besoin de `finally` :) -# avec with +```python +try: + with file = open(filename): + lines = file.readlines() +except FileNotFoundError: + print("Fichier non trouvé") +``` +L'exception est capturée, le fichier est fermé, puis l'exception est +levée à nouveau. -# attention a ou vous mettez except +# Attention à la position du except ```python if truc: @@ -150,6 +199,8 @@ if truc: raise MyError("kaboom!") ```` +# Attention à la position du except + ```python if truc: if machin: @@ -161,6 +212,7 @@ if truc: ``` +# Attention à la position du except ```python if truc: @@ -173,9 +225,45 @@ if truc: ```` +# Accédér aux détails de l'exception + +* Avec `as`: + +```python + +try: + something_dangerous() +except FileNotFoundError as error: + print("file not found:", error.filename) +``` + +\vfill -# Accédér aux détails de l'exceptions +Voir la documentation pour les attributs disponibles. + + +# Lever une exception + +* Avec raise + +```python +def retirer_somme(compte, montant): + solde = ... + if montant >= solde: + raise ValueError("montant supérieur au solde!") +``` + +# Créer vos propres exceptions + +Toujours hériter de `Exception`. + +```python +class BankError(Exception): + .... + +class NotEnoughMoney(BankError): + def __init__(self, amount, withdrawal): + self.amount = amount + self.withdrawal = withdrawal +``` -* Avec `as` -* Attrribut `args` -* Parfois d'autres atttributs (voir la doc)