Exceptions
Progression
#Exceptions
À quoi ça sert ?
À quoi ça sert: signaler proprement les situations anormales et garantir la libération des ressources. Comment: try/except/else/finally
, exceptions spécifiques, chaînage, et context managers pour le nettoyage.
Objectifs d’apprentissage
- Utiliser
try/except/else/finally
selon l’intention (gestion d’erreur, nettoyage).- Lever des exceptions précises et les chaîner (
raise ... from e
).- Écrire des context managers (
with
) pour garantir la libération de ressources.
pythonpython
1try:2 1/03except ZeroDivisionError:4 print('division par zéro !')5finally:6 print('Toujours exécuté')
Spécificité d’abord
Interceptez des exceptions précises (ex: ValueError
, KeyError
) et laissez les autres remonter. Évitez except Exception
sans re‑raise ciblé.
Lever des exceptions personnalisées:
pythonpython
1def racine(n: float) -> float:2 if n < 0:3 raise ValueError('n doit être >= 0')4 return n ** 0.55 6print(racine(9))
Chaînage et granularité:
pythonpython
1class PaymentError(Exception):2 pass3 4def pay():5 try:6 1/07 except ZeroDivisionError as e:8 raise PaymentError('échec paiement') from e9 10try:11 pay()12except PaymentError as e:13 print('Business error:', e.__cause__.__class__.__name__)
#Playground
Chargement de l’éditeur...
#Exercices
- Écrire un parseur robuste pour des lignes
a;b;c
(skip lignes invalides, rapport d’erreurs). - Écrire un contexte
timer()
qui mesure la durée d’un bloc (viawith
).
#Pièges fréquents
except Exception:
trop large masque des bugs; préférez des exceptions précises.- Ne pas oublier
finally
(ou context manager) pour libérer fichiers/verrous/sockets. raise
vsreturn
dansfinally
: unreturn
dansfinally
supprime l’exception — à éviter.
#Danger: return
dans finally
pythonpython
1def f():2 try:3 1/04 finally:5 return 'masque l\'exception' # à éviter6 7print(f()) # L'exception ZeroDivisionError est perdue !
Règle simple: ne pas retourner depuis finally
. Faites les nettoyages, puis laissez l’exception remonter.
#Relancer proprement
pythonpython
1try:2 ouvrir_fichier()3except OSError as e:4 # Ajouter du contexte sans perdre la trace d'origine5 raise RuntimeError('échec ouverture fichier config') from e
#Nettoyages et context managers
Utilisez with
pour garantir la fermeture/libération:
pythonpython
1from contextlib import contextmanager2 3@contextmanager4def timer():5 import time6 t0=time.perf_counter();7 try:8 yield9 finally:10 print(f"{(time.perf_counter()-t0)*1e3:.1f} ms")11 12with timer():13 sum(range(10_000))
#Quiz éclair
Lequel garantit l’exécution même en cas d’exception ?