Erreurs et exceptions Python3
En tant que débutant en Python, lorsque vous apprenez pour la première fois la programmation Python, vous voyez souvent des messages d'erreur. Nous ne les avons pas mentionnés auparavant ; ce chapitre les présentera spécifiquement.
Python a deux types d'erreurs faciles à reconnaître : les erreurs de syntaxe et les exceptions.
Python (assertion) est utilisé pour évaluer une expression, et déclenche une exception si la condition de l'expression est fausse.

Erreurs de syntaxe
Les erreurs de syntaxe Python, également appelées erreurs d'analyse, sont souvent rencontrées par les débutants, comme dans l'exemple suivant :
File "<stdin>", line 1, in ?
while True print('Hello world')
^
SyntaxError: syntaxe invalide
Dans cet exemple, la fonction print() est détectée comme comportant une erreur : il manque un deux-points avant elle.: 。
L'analyseur syntaxique indique la ligne contenant l'erreur et marque une petite flèche à la position où l'erreur a été détectée pour la première fois.
Exceptions
Même si la syntaxe d'un programme Python est correcte, des erreurs peuvent encore se produire lors de son exécution. Les erreurs détectées pendant l'exécution sont appelées exceptions.
La plupart des exceptions ne sont pas gérées par le programme et apparaissent ici sous forme de messages d'erreur :
Exemple
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ZeroDivisionError: division par zéro
>>> 4 + spam*3 # spam n'est pas défini, déclenche une exception
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: le nom 'spam' n'est pas défini
>>> '2' + 2 # int ne peut pas être ajouté à str, déclenche une exception
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: on ne peut concaténer que str (pas "int") à str
Les exceptions apparaissent sous différents types, et ces types sont tous imprimés dans les informations : les types dans l'exemple sont ZeroDivisionError, NameError et TypeError.
La partie avant du message d'erreur montre le contexte dans lequel l'exception s'est produite et affiche des informations spécifiques sous la forme d'une pile d'appels.
Gestion des exceptions
try/except
Les exceptions peuvent être interceptées à l'aide de l'instructiontry/except.

Dans l'exemple suivant, il est demandé à l'utilisateur de saisir un entier valide, mais l'utilisateur est autorisé à interrompre le programme (à l'aide de Control-C ou d'une méthode fournie par le système d'exploitation). L'interruption de l'utilisateur déclenchera une exception KeyboardInterrupt.
try:
x = int(input("Veuillez saisir un nombre : "))
break
except ValueError:
print("Vous n'avez pas saisi de nombre, veuillez réessayer !")
L'instruction try fonctionne comme suit :
Tout d'abord, la clause try est exécutée (les instructions entre le mot-clé try et le mot-clé except).
Si aucune exception ne se produit, la clause except est ignorée, et la clause try se termine après exécution.
Si une exception se produit pendant l'exécution de la clause try, le reste de la clause try est ignoré. Si le type de l'exception correspond au nom après except, alors la clause except correspondante sera exécutée.
Si une exception ne correspond à aucun except, alors cette exception sera transmise à un try extérieur.
Une instruction try peut contenir plusieurs clauses except pour gérer respectivement différentes exceptions spécifiques. Au plus une branche sera exécutée.
Le gestionnaire ne traitera que les exceptions dans la clause try correspondante, et non les exceptions dans les gestionnaires d'autres instructions try.
Une clause except peut gérer plusieurs exceptions en même temps ; ces exceptions sont mises entre parenthèses pour former un tuple, par exemple :
pass
La dernière clause except peut omettre le nom de l'exception, et elle sera utilisée comme un joker. Vous pouvez utiliser cette méthode pour afficher un message d'erreur, puis lever à nouveau l'exception.
try:
f = open('myfile.txt')
s = f.readline()
i = int(s.strip())
except OSError as err:
print("OS error: {0}".format(err))
except ValueError:
print("Could not convert data to an integer.")
except:
print("Unexpected error:", sys.exc_info()[0])
raise
try/except...else
try/exceptL'instruction comporte également uneelseclause facultative. Si cette clause est utilisée, elle doit être placée après toutes les clauses except.
La clause else sera exécutée lorsqu'aucune exception ne se produit dans la clause try.

L'exemple suivant vérifie dans une instruction try si le fichier peut être ouvert. Si le fichier s'ouvre normalement sans exception, la partie else est exécutée pour lire le contenu du fichier :
try:
f = open⟧(arg, 'r')
except IOError:
print('cannot open', arg)
else:
print(arg, 'has', len(f.readlines()), 'lines')
f.close()
Utiliser la clause else est préférable à placer toutes les instructions dans la clause try, car cela évite certaines exceptions inattendues que except ne peut pas intercepter.
La gestion des exceptions ne traite pas seulement les exceptions qui se produisent directement dans la clause try, mais aussi les exceptions levées dans les fonctions appelées dans la clause (même les fonctions appelées indirectement). Par exemple :
x = 1/0
>>> try:
this_fails()
except ZeroDivisionError as err:
print('Gestion de l'erreur d'exécution :', err)
Gestion de l'erreur d'exécu tion : division entière ou modulo par zéro
Instruction try-finally
L'instruction try-finally exécute le code final, qu'une exception se produise ou non.

Dans l'exemple suivant, l'instruction finally s'exécute, qu'une exception se produise ou non :
Exemple
exemple()
except AssertionError as error:
print(error)
else:
try:
with open('file.log') as file:
read_data = file.read()
except FileNotFoundError as fnf_error:
print(fnf_error)
finally:
print('Cette phrase sera exécutée, qu'une exception se produise ou non.')
Lever des exceptions
Python utilise l'instruction raise pour lever une exception spécifiée.
Le format de la syntaxe de raise est le suivant :
raise [Exception [, args [, traceback]]]

L'exemple suivant lève une exception si x est supérieur à 5 :
if x > 5:
raise Exception('x ne peut pas être supérieur à 5. La valeur de x est : {}'.format(x))
L'exécution du code ci-dessus lèvera une exception :
Traceback (most recent call last):
File "test.py", line 3, in <module>
raise Exception('x 不能大于 5。x 的值为: {}'.format(x))
Exception: x 不能大于 5。x 的值为: 10
Le seul paramètre de raise spécifie l'exception à lever. Il doit être une instance d'une exception ou une classe d'exception (c'est-à-dire une sous-classe de Exception).
Si vous voulez seulement savoir si une exception a été levée, et ne voulez pas la gérer, alors une simple instruction raise peut la relancer.
raise NameError('HiThere') # Simuler une exception.
except NameError:
print('Une exception est passée !')
raise
Une exception est passée!
Traceback (most recent call last):
File "<stdin>", line 2, in ?
NameError: HiThere
Exceptions définies par l'utilisateur
Vous pouvez avoir vos propres exceptions en créant une nouvelle classe d'exception. La classe d'exception hérite de la classe Exception, directement ou indirectement, par exemple :
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)
>>> try:
raise MyError(2*2)
except MyError as e:
print('Mon exception est survenue, valeur :', e.value)
Mon exception est survenue, valeur : 4
>>> raise MyError('oups !')
Traceback (most recent call last):
File "<stdin>", line 1, in ?
__main__.MyError: 'oups !'
Dans cet exemple, la méthode __init__() par défaut de la classe Exception est redéfinie.
Lorsqu'un module peut lever plusieurs exceptions différentes, une pratique courante consiste à créer une classe d'exception de base pour ce paquet, puis à créer différentes sous-classes pour différentes situations d'erreur en fonction de cette classe de base :
"""Classe de base pour les exceptions dans ce module."""
pass
class InputError(Error):
"""Exception levée pour les erreurs dans l'entrée.
Attributs :
expression -- expression d'entrée dans laquelle l'erreur s'est produite
message -- explication de l'erreur
"""
def __init__(self, expression, message):
self.expression = expression
self.message = message
class TransitionError(Error):
"""Levée lorsqu'une opération tente une transition d'état qui n'est pas
autorisée.
Attributs :
previous -- état au début de la transition
next -- nouvel état tenté
message -- explication de la raison pour laquelle la transition spécifique n'est pas autorisée
"""
def __init__(self, previous, next, message):
self.précédent = précédent
self.suivant = suivant
self.message = message
La plupart des noms d'exceptions se terminent par 'Error', tout comme la convention de nommage standard des exceptions.
Définition des actions de nettoyage
L'instruction try possède une autre clause optionnelle qui définit des actions de nettoyage qui sont exécutées dans toutes les circonstances. Par exemple :
... raise KeyboardInterrupt
... finally:
... print('Goodbye, world!')
...
Goodbye, world!
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
KeyboardInterrupt
Dans l'exemple ci-dessus, qu'une exception se produise ou non dans la clause try, la clause finally sera exécutée.
Si une exception est levée dans la clause try (ou dans les clauses except et else), et qu'aucune clause except ne la capture, alors cette exception sera levée après l'exécution de la clause finally.
Voici un exemple plus complexe (contenant à la fois des clauses except et finally dans la même instruction try) :
try:
result = x / y
except ZeroDivisionError:
print("division by zero!")
else:
print("le résultat est", result)
finally:
print("exécution de la clause finally")
>>> divide(2, 1)
result est 2.0
exécution de la finally clause
>>> divide(2, 0)
division par zéro!
exécution de la finally clause
>>> divide("2", "1")
exécution de la finally clause
Traceback (most recent call last):
File "<stdin>", line 1, in ?
Fichier "<stdin>", ligne 3, dans divide
TypeError: opérande non pris en charge de type(s) pour /: 'str' et 'str'
Actions de nettoyage prédéfinies
Certains objets définissent un comportement de nettoyage standard. Que le système l'ait utilisé avec succès ou non, une fois qu'il n'est plus nécessaire, ce comportement de nettoyage standard sera exécuté.
L'exemple suivant montre comment essayer d'ouvrir un fichier puis d'afficher son contenu à l'écran :
print(line, end="")
Le problème avec le code ci-dessus est qu'après exécution, le fichier reste ouvert et n'est pas fermé.
L'instruction avec le mot-clé with peut garantir que des objets tels que les fichiers exécuteront correctement leur méthode de nettoyage après utilisation :
for line in f:
print(line, end="")
Une fois le code ci-dessus exécuté, même si un problème survient pendant le traitement, le fichier f sera toujours fermé.
Pour plus de contenu sur le mot-clé with, consultez :Mot-clé with de Python