W3docs

Python Try...Except

Apprenez les blocs try, except, else et finally en Python avec des exemples clairs. Gérez ZeroDivisionError, ValueError, FileNotFoundError et plus encore.

Lorsque Python rencontre une erreur à l'exécution, il lève une exception — un objet qui représente ce qui s'est mal passé. Sans aucune gestion, une exception termine immédiatement votre programme. L'instruction try...except vous permet d'attraper ces exceptions, d'y répondre de manière appropriée et de maintenir votre programme en cours d'exécution.

Ce chapitre couvre :

  • Le bloc try / except — attraper une exception spécifique
  • Capturer les détails d'une exception avec as
  • Les clauses except multiples et la capture de plusieurs exceptions à la fois
  • Le bloc else — code qui s'exécute uniquement lorsqu'aucune exception ne se produit
  • Le bloc finally — code de nettoyage qui s'exécute toujours
  • Les exceptions intégrées courantes et quand elles se produisent
  • La re-levée d'exceptions
  • Les bonnes pratiques et les erreurs courantes

Le bloc try...except de base

Entourez le code susceptible d'échouer dans un bloc try. Si Python lève une exception, l'exécution saute vers le bloc except correspondant au lieu de planter.

python— editable, runs on the server

Sortie :

Error: division by zero

Python tente la division, lève ZeroDivisionError, et le bloc except la gère. La clause as e lie l'objet exception à e afin que vous puissiez inspecter ou journaliser le message.

Si le bloc try réussit, le bloc except est entièrement ignoré.

Attraper un type d'exception spécifique

Nommez toujours le type d'exception que vous attendez. Attraper un type nommé rend votre intention claire et évite de masquer accidentellement des bugs sans rapport.

try:
    number = int("abc")
except ValueError as e:
    print(f"Could not convert: {e}")

Sortie :

Could not convert: invalid literal for int() with base 10: 'abc'

int("abc") lève ValueError car "abc" n'est pas un entier valide. Spécifier ValueError dans la clause except signifie que toute autre exception inattendue se propagera quand même et apparaîtra comme une erreur plutôt que d'être silencieusement ignorée.

Les clauses except multiples

Un seul bloc try peut avoir plusieurs clauses except — Python les vérifie de haut en bas et exécute la première correspondance.

def safe_index(items, index):
    try:
        return items[index]
    except IndexError:
        print("Index out of range.")
    except TypeError:
        print("Index must be an integer.")

safe_index([1, 2, 3], 10)   # IndexError
safe_index([1, 2, 3], "a")  # TypeError

Sortie :

Index out of range.
Index must be an integer.

L'ordre est important : placez les types d'exceptions plus spécifiques avant les types plus larges afin que le gestionnaire spécifique s'exécute en premier.

Attraper plusieurs exceptions dans une seule clause

Lorsque deux exceptions ou plus méritent la même réponse, regroupez-les dans un tuple :

try:
    value = int("not-a-number")
except (ValueError, TypeError) as e:
    print(f"Input error: {e}")

Sortie :

Input error: invalid literal for int() with base 10: 'not-a-number'

Le bloc else

Le bloc else s'exécute uniquement lorsque le bloc try se termine sans lever aucune exception. Utilisez-le pour le code qui doit s'exécuter en cas de succès mais qui n'a pas lui-même besoin de protection contre les erreurs :

try:
    result = 10 / 2
except ZeroDivisionError:
    print("Cannot divide by zero.")
else:
    print(f"Division succeeded. Result: {result}")

Sortie :

Division succeeded. Result: 5.0

Garder la logique du chemin de succès dans else (plutôt qu'au bas du bloc try) évite d'attraper accidentellement des exceptions que le code du chemin de succès lui-même pourrait lever.

Le bloc finally

Le bloc finally s'exécute quoi qu'il arrive — que le bloc try réussisse, qu'une exception soit attrapée, ou qu'une exception se propage sans être attrapée. Utilisez-le pour le nettoyage : fermer des fichiers, libérer des verrous ou se déconnecter d'une base de données.

try:
    result = 10 / 0
except ZeroDivisionError:
    print("Error caught.")
finally:
    print("This always runs — cleanup goes here.")

Sortie :

Error caught.
This always runs — cleanup goes here.

Même si vous commentez le bloc except, finally s'exécute quand même avant que Python ne propage l'exception.

Structure complète en un coup d'œil

try:
    # code that may raise an exception
except SomeException as e:
    # handle the exception
except (AnotherError, YetAnother):
    # handle either of these
else:
    # runs only when try succeeded
finally:
    # always runs

Les exceptions intégrées courantes

ExceptionQuand elle se produit
ZeroDivisionErrorDivision ou modulo par zéro
ValueErrorBon type, mauvaise valeur (ex. int("abc"))
TypeErrorOpération appliquée au mauvais type
IndexErrorIndice de séquence hors limites
KeyErrorClé de dictionnaire introuvable
FileNotFoundErrorFichier ou répertoire inexistant
AttributeErrorL'objet n'a pas cet attribut
ImportErrorLe module ne peut pas être importé
NameErrorLe nom de variable n'est pas défini

Toutes ces exceptions héritent de la classe de base Exception. Vous pouvez attraper Exception pour les gérer toutes dans une seule clause, mais préférez les types spécifiques dans la mesure du possible.

Gérer un fichier manquant

try:
    with open("data.txt", "r") as file:
        content = file.read()
except FileNotFoundError:
    print("Error: File not found.")

Sortie (lorsque data.txt n'existe pas) :

Error: File not found.

Re-lever une exception

Parfois, vous souhaitez journaliser une exception ou effectuer un nettoyage partiel, mais laisser quand même l'exception se propager à l'appelant. Utilisez un raise nu à l'intérieur d'un bloc except :

def process():
    try:
        result = 10 / 0
    except ZeroDivisionError:
        print("Logging error...")
        raise  # re-raises the original ZeroDivisionError

try:
    process()
except ZeroDivisionError as e:
    print(f"Outer handler caught: {e}")

Sortie :

Logging error...
Outer handler caught: division by zero

Le raise nu préserve la traceback originale afin que le débogage ne soit pas plus difficile qu'en l'absence du gestionnaire.

Attraper la classe de base Exception

Vous pouvez utiliser Exception comme gestionnaire fourre-tout pour toute erreur qui ne fait pas quitter le système :

try:
    result = 10 / 0
except Exception as e:
    print(f"An error occurred: {type(e).__name__}: {e}")

Sortie :

An error occurred: ZeroDivisionError: division by zero

type(e).__name__ vous donne le nom de la classe spécifique même lorsque vous attrapez via la classe de base. Cela est utile dans les gestionnaires de niveau supérieur où vous souhaitez journaliser chaque erreur inattendue.

bare except — et pourquoi l'éviter

Un bare except (sans type d'exception) attrape littéralement tout, y compris KeyboardInterrupt (Ctrl+C) et SystemExit, rendant votre programme difficile à interrompre :

# Avoid this pattern
try:
    result = 10 / 0
except:
    print("Some error occurred")

Préférez except Exception si vous avez besoin d'un large filet, car cela laisse quand même KeyboardInterrupt et SystemExit se propager normalement.

Bonnes pratiques

  • Soyez spécifique. Attrapez le type d'exception le plus étroit qui ait du sens.
  • Ne silenciez pas les exceptions. Journalisez au minimum l'erreur ; ne laissez jamais un bloc except vide.
  • Utilisez else pour le code du chemin de succès. Cela maintient le bloc try aussi petit que possible.
  • Utilisez finally pour le nettoyage. Ou, encore mieux, utilisez une instruction with — voir Python with Statement.
  • Évitez le bare except. Utilisez except Exception si vous avez besoin d'un large filet.
  • Re-levez si nécessaire. Si vous ne pouvez pas gérer complètement l'erreur, laissez-la se propager avec raise.

Pour lever des exceptions délibérément et créer vos propres classes d'exceptions, voir Python raise and Custom Exceptions.

Pratique

Pratique
What is the functionality of 'Try' and 'Except' in Python?
What is the functionality of 'Try' and 'Except' in Python?
Was this page helpful?