Maison >développement back-end >Tutoriel Python >Tutoriel de base Python 2.7 : erreurs et exceptions
.. _tut-erreurs :
===================================
Erreurs et exceptions Erreurs et exceptions
================================== === =
Jusqu'à présent, les messages d'erreur n'ont pas été plus que mentionnés, mais si vous avez essayé
les exemples, vous en avez probablement vu. Il y en a (au moins) deux<.>
Types d'erreurs distinctifs : *erreurs de syntaxe* et *exceptions*.Pas de discussion plus approfondie sur les messages d'erreur jusqu'à présent, mais dans les exemples que vous avez expérimentés, Vous j'en ai peut-être rencontré. Il existe (au moins) deux types d'erreurs en Python : *erreurs de syntaxe* et *exceptions* . .. _tut-syntaxerrors :Erreurs de syntaxe Erreurs de syntaxe====================== Les erreurs de syntaxe, également connues sous le nom d'erreurs d'analyse, sont peut-être le type de plainte le plus courantque vous recevez pendant que vous apprenez encore Python :Erreurs de syntaxe, également connues sous le nom de Les erreurs d'interprétation peuvent être les erreurs les plus courantes dans le processus d'apprentissage de Python :: >>> while True print 'Hello world' File "causée par (ou au moins détectée au niveau) du jeton *précédant* la flèche : dans l'exemple
, l'erreur est détectée au niveau du mot-clé :keyword:`print`, puisqu'un deux-points
(``':'``) est manquant avant. Le nom du fichier et le numéro de ligne sont imprimés afin que vous
savez où chercher au cas où l'entrée proviendrait d'un script.
L'analyseur répétera la ligne avec l'erreur et affichera une petite "flèche". L'erreur
(au moins celle qui est détectée) se produit là où la flèche *pointe*. L'erreur dans l'exemple apparaît sur le mot-clé
:keyword:`print` car il manque deux points ( ``':'`` ) avant celui-ci. Le nom du fichier et le numéro de ligne seront également affichés,
afin que vous puissiez savoir de quel script vient l'erreur et d'où.
.. _tut-exceptions :
Exceptions
==========
Même si une instruction ou une expression est syntaxiquement correcte , cela peut provoquer une
erreur lorsqu'on tente de l'exécuter. Les erreurs détectées lors de l'exécution
sont appelées *exceptions* et ne sont pas inconditionnellement fatales : vous l'apprendrez bientôt
comment les gérer dans les programmes Python. Cependant, la plupart des exceptions ne sont pas gérées par
programmes et entraînent des messages d'erreur comme indiqué ici :
Même les instructions qui sont complètement grammaticalement correctes, un une erreur peut également se produire lors de la tentative de son exécution. Les erreurs détectées lors de
l'exécution d'un programme sont appelées exceptions. Elles ne provoquent généralement pas de problèmes fatals, et vous apprendrez bientôt
comment les contrôler dans les programmes Python. La plupart des exceptions ne seront pas gérées par le programme, mais afficheront un message d'erreur : :
>>> 10 * (1/0)
Traceback (dernier appel le plus récent) :
Fichier "
ZeroDivisionError : division entière ou modulo par zéro
>>
Traceback (dernier appel le plus récent) :
Fichier "
NameError : le nom 'spam' n'est pas défini
>>> '2' 2
Traceback (dernier appel le plus récent) :
Fichier "
TypeError : impossible de concaténer les objets 'str' et 'int'
La dernière ligne du message d'erreur indique ce qui s'est passé. Les exceptions sont de différents types, et le type est imprimé comme. partie du message : les types dans
l'exemple sont :exc:`ZeroDivisionError`, :exc:`NameError` et :exc:`TypeError`.
La chaîne imprimée comme exception type est le nom de l'exception intégrée
qui s'est produite. Cela est vrai pour toutes les exceptions intégrées, mais ne doit pas nécessairement être vrai
pour les exceptions définies par l'utilisateur (bien qu'il s'agisse d'une exception intégrée). convention utile). Les noms d'exception standard
sont des identifiants intégrés (pas des mots-clés réservés).
La dernière ligne du message d'erreur indique quelle erreur s'est produite. Les exceptions ont également différents types. Le type d'exception est affiché dans le cadre du message d'erreur
: les exceptions dans l'exemple sont l'erreur de division zéro
( :exc:`ZeroDivisionError` ) et l'erreur de nom. ( :exc:`NameError`) et tapez
erreur (:exc:`TypeError`). Lors de l'impression des informations d'erreur, le type d'exception est utilisé comme nom intégré de l'exception
Affichage. Cela est vrai pour toutes les exceptions intégrées, mais pas nécessairement pour les exceptions définies par l'utilisateur (bien que ce
soit une convention utile). Les noms d'exception standard sont des identifiants intégrés (pas de mots-clés réservés).
Le reste de la ligne fournit des détails basés sur le type d'exception et ce
qui l'a provoquée. Cela signifie que son contenu dépend du type d'exception.
La partie précédente du message d'erreur montre le contexte dans lequel l'exception
s'est produite, sous la forme d'un traçage de pile. En général, elle contient une source de liste de traçage de pile
. lignes ; cependant, il n'affichera pas les lignes lues à partir de
entrée standard.
La première moitié du message d'erreur répertorie l'emplacement où l'exception s'est produite sous la forme d'une pile. Normalement, les lignes de code source sont répertoriées sur la pile, cependant, le code source provenant de l'entrée standard n'est pas affiché.
:ref:`bltin-exceptions` répertorie les exceptions intégrées et leurs significations.
.. _tut-handling :
Gestion des exceptions Contrôler les exceptions
====================== ======
Il est possible d'écrire des programmes qui gèrent les exceptions sélectionnées
exemple suivant, qui demande à l'utilisateur une saisie jusqu'à ce qu'un entier valide soit
.entré, mais permet à l'utilisateur d'interrompre le programme (en utilisant :kbd:`Control-C` ou
tout ce que le système d'exploitation prend en charge
) ; est signalé en déclenchant l'exception :exc:`KeyboardInterrupt` :
Les programmes peuvent être écrits pour contrôler les exceptions connues. Voir l'exemple ci-dessous, qui demande à l'utilisateur de saisir des informations jusqu'à ce que
obtienne un entier valide, et permet à l'utilisateur d'interrompre le programme (en utilisant :kbd:`Control-C` ou
quelque chose else Opérations prises en charge par le système d'exploitation); il convient de noter que les interruptions générées par l'utilisateur lèveront l'exception
:exc:`KeyboardInterrupt`. ::
>>> while True:
... try:
... x = int(raw_input("Veuillez entrer un nombre : " ))
... pause
... sauf ValueError :
... imprimer "Oups ! Ce numéro n'était pas valide. Réessayez..."
...
L'instruction :keyword:`try` fonctionne comme suit.
:keyword:`try` fonctionne comme suit.
* Tout d'abord, la *clause try* (la ou les instructions entre les mots-clés :keyword:`try` et
:keyword:`sauf`) est exécutée.
Tout d'abord, exécutez la *clause try* (la partie entre les mots-clés :keyword:`try` et :keyword:`sauf`).
* Si aucune exception ne se produit, la *clause except* est ignorée et l'exécution de l'instruction
:keyword:`try` est terminée.
Si aucune exception ne se produit, La *clause except* est ignorée une fois l'exécution de l'instruction :keyword:`try` terminée.
* Si une exception se produit lors de l'exécution de la clause try, le reste de la clause
est ignoré. Ensuite, si son type correspond à l'exception nommée d'après le
:keyword. :`sauf` le mot-clé, la clause except est exécutée, puis l'exécution
continue après l'instruction :keyword:`try`.
Si une exception se produit lors de l'exécution de la clause try, Ensuite, le reste de la clause est ignoré.
Si l'exception correspond au type d'exception spécifié après le mot-clé :keyword:`sauf`, la clause except correspondante
sera exécutée. Continuez ensuite à exécuter le code après l'instruction :keyword:`try`.
* Si une exception se produit qui ne correspond pas à l'exception nommée dans la clause except
, elle est transmise aux instructions externes :keyword:`try` si aucun gestionnaire n'est
;trouvé, il s'agit d'une *exception non gérée* et l'exécution s'arrête avec un message comme
indiqué ci-dessus.
Si une exception se produit, il n'y a pas d'exception correspondante dans la branche de la clause except, il sera transmis à l'instruction
niveau supérieur:keyword:`try`. Si l'instruction de traitement correspondante n'est toujours pas trouvée à la fin, elle devient
comme une *exception non gérée*, termine le programme et affiche un message d'invite.
Une instruction :keyword:`try` peut avoir plus d'une clause except, pour spécifier
gestionnaires pour différentes exceptions.
Gestionnaires. ne gère que les exceptions qui se produisent dans la clause try correspondante, pas
dans les autres gestionnaires de la même instruction :keyword:`try`. Une clause except peut
nommer plusieurs exceptions sous forme de tuple entre parenthèses, par exemple :
Une instruction :keyword:`try` peut contenir plusieurs clauses except, chacune spécifiant la gestion de différentes exceptions
. Au maximum, une seule branche sera exécutée. Le gestionnaire d'exceptions ne gérera que la clause try correspondante
Les exceptions qui se produisent dans la même instruction :keyword:`try`, les exceptions qui se produisent dans d'autres clauses ne seront pas traitées
. Une clause except peut répertorier plusieurs noms d'exception entre parenthèses, par exemple ::
... except (RuntimeError, TypeError, NameError):
... pass
Le La dernière clause except peut omettre le(s) nom(s) d'exception, pour servir de caractère générique.
Utilisez-la avec une extrême prudence, car il est facile de masquer une véritable erreur de programmation
de cette manière ! Il peut également être utilisé pour imprimer un message d'erreur, puis relancer
l'exception (permettant à un appelant de gérer également l'exception) :
dernière clause except Vous pouvez omettre le nom de l'exception et utilisez-le comme caractère générique. Assurez-vous d'utiliser
cette méthode avec prudence, car elle est susceptible de masquer de véritables erreurs de programme et d'empêcher les gens de les découvrir ! Il peut également être utilisé pour imprimer une ligne d'informations d'erreur, puis renvoyer l'exception (ce qui permet à l'appelant de mieux gérer l'exception) ::
import sys
try:
f = open('myfile.txt')
s = f.readline()
i = int(s.strip())
sauf IOError comme (errno, strerror):
imprimer "Erreur d'E/S ({0}): {1}".format(errno, strerror)
sauf ValueError:
print "Impossible de convertir les données en nombre entier."
sauf :
print "Erreur inattendue :", sys.exc_info()[0]
raise
L'instruction :keyword:`try` ... :keyword:`sauf` a une clause facultative *else
clause*, qui, lorsqu'elle est présente, doit suivre toutes les clauses except. Elle est utile pour<.>
code qui doit être exécuté si la clause try ne déclenche pas d'exception. Pourexemple ::keyword:`try` ... :keyword :`sauf`. La déclaration peut avoir une *clause else*, Cette clause ne peut apparaître qu'après toutes les clauses sauf les clauses. Lorsque l'instruction try ne lève pas d'exception et que du code doit être exécuté, vous pouvez utiliser la clause . Par exemple :: pour arg dans sys.argv[1:]: try: f = open(arg, 'r') sauf IOError : print 'ne peut pas ouvrir', arg 🎜>f.close()
L'utilisation du :keyword:`else`. est préférable que d'ajouter du code supplémentaire à
la clause :keyword:`try` car elle évite d'attraper accidentellement une exception
qui n'a pas été déclenchée par le code protégé par le :keyword: `try` ...
:keyword:`sauf` instruction.
Il est préférable d'utiliser une clause :keyword:`else` que d'ajouter du code dans une clause :keyword:`try` car
cela évite :keyword:`try` ... :keyword:`sauf ` Les interceptions inattendues ne sont pas censées être des
exceptions lancées par le code qu'elles protègent.
Lorsqu'une exception se produit, elle peut avoir une valeur associée, également connue sous le nom de
*argument* de l'exception. La présence et le type de l'argument dépendent de l'
exception. tapez.
Lorsqu'une exception se produit, il peut y avoir une valeur attachée qui existe en tant que *paramètre* de l'exception. L'existence de ce paramètre et son type
dépendent du type d'exception.
La clause except peut spécifier une variable après le nom de l'exception (ou tuple).
La variable est liée à une instance d'exception avec les arguments stockés dans
``instance .args``. Pour plus de commodité, l'instance d'exception définit
:meth:`__str__` afin que les arguments puissent être imprimés directement sans avoir à
référence ``.args``.
Après le nom de l'exception (liste), vous pouvez également spécifier une variable pour la clause except. Cette variable est liée à
une instance d'exception, qui est stockée dans les arguments de ``instance.args``. Pour plus de commodité, l'instance d'exception
définit :meth:`__str__` afin que les paramètres d'impression soient accessibles directement sans référencer
``.args``.
On peut également instancier une exception avant de la déclencher et y ajouter des
attributs comme on le souhaite :
Cette pratique n'est pas encouragée. Au lieu de cela, une meilleure approche consiste à transmettre un paramètre à l'exception (ou un tuple si vous souhaitez transmettre plusieurs paramètres
) et à le lier à la propriété message. Une fois qu'une exception se produit, elle
lie toutes les propriétés spécifiées avant de les lancer. ::
>>> essayez :
... déclenche une Exception('spam', 'eggs')
... sauf Exception en tant qu'inst :
... print type(inst) # l'instance d'exception
... print inst.args # arguments stockés dans .args
... print inst ... # __str__ permet d'imprimer les arguments directement
... x, y = inst # __getitem__ permet de décompresser les arguments directement
... print 'x = ', x
... imprimer 'y =', y
...
('spam', 'œufs')
('spam', 'œufs')
x = spam
y = œufs
Si une exception a un argument, celui-ci est imprimé comme dernière partie (« détail ») du message pour les exceptions non gérées. Il sera imprimé comme dernière partie du message d'erreur
<.> ("Détails"). Les gestionnaires d'exceptions ne gèrent pas seulement les exceptions si elles se produisent immédiatement dans laclause try, mais aussi si elles se produisent à l'intérieur de fonctions appelées (mêmeindirectement) dans la clause try. Par exemple :Le gestionnaire de gestion des exceptions peut non seulement gérer les exceptions qui se produisent directement dans la clause try, même si une exception se produit dans la fonction appelée dans celle-ci (même est indirecte) , peut être traité de la même manière. Par exemple : : >>> def this_fails(): ... x = 1/0 ... > ;>> essayez : ... this_fails() ... sauf ZeroDivisionError comme détail : ... print 'Gestion de l'erreur d'exécution : ', détail ... Gestion des erreurs d'exécution : division entière ou modulo par zéro.. _tut-raising:Raising Exceptions Lever une exception============================Le :keyword:`raise` L'instruction permet au programmeur de forcer uneexception spécifiée à se produire. Par exemple :Le programmeur peut utiliser l'instruction :keyword:`raise` pour forcer l'exception spécifiée à se produire. Par exemple : : >>> raise NameError('HiThere') Traceback (dernier appel le plus récent) : Fichier "être dérivé de la classe :exc:`Exception`, directement ou indirectement. Par
exemple :
Vous pouvez nommer vos propres exceptions en créant de nouveaux types d'exceptions dans le programme. (Python Pour le contenu du cours, veuillez consulter
see:ref:`tut-classes`). Les classes d'exception doivent généralement être dérivées directement ou indirectement de la classe
:exc:`Exception`, par exemple ::
>>>
... def __init__(self, value): ... self.value = valeur ... def __str__(self): . .. return repr(self.value) ... >>> essayez : ... raise MyError(2*2) ... sauf MyError comme e: ... imprimer 'Mon exception s'est produite, valeur :', e.value ... Mon une exception s'est produite, valeur : 4 >>> raise MyError('oops!')Traceback (dernier appel le plus récent) :
Fichier "
__main__.MyError : 'oops !'
Dans cet exemple, la valeur par défaut :meth:`__init__` de :class:`Exception` a été
remplacée. Le nouveau comportement crée simplement l'attribut *value* Ceci
remplace la valeur par défaut. comportement de création de l'attribut *args*.
Dans cet exemple, le :class:`Exception` par défaut :meth:`__init__` est remplacé. Nouvelle façon de créer simplement des
attributs de valeur. Cela remplace la manière originale de créer des attributs *args*.
Des classes d'exception peuvent être définies qui font tout ce que n'importe quelle autre classe peut faire, mais
sont généralement simples, n'offrant souvent qu'un certain nombre d'attributs qui permettent
des informations sur le erreur à extraire par les gestionnaires pour l'exception. Lors de la
création d'un module pouvant générer plusieurs erreurs distinctes, une pratique courante consiste
à créer une classe de base pour les exceptions définies par ce module, et sous-classe qui
pour créer des classes d'exception spécifiques pour différentes conditions d'erreur :
Les classes d'exception peuvent définir tout ce qui peut être défini dans d'autres classes, mais généralement pour rester simple, uniquement dans
Ajoutez plusieurs informations d'attribut pour l'extraction du gestionnaire de gestion des exceptions. Si un module nouvellement créé doit
générer plusieurs erreurs différentes, une approche courante consiste à définir une classe de base d'exception pour le module, puis à cibler
pour différents types d'erreurs. Dérivez la sous-classe d'exception correspondante. . ::
class Error(Exception):
"""Classe de base pour les exceptions dans ce module."""
pass
class InputError( Erreur):
"""Exception levée pour les erreurs dans l'entrée.
Attributs :
expr -- expression d'entrée dans laquelle l'erreur s'est produite
msg -- explication de l'erreur
"""
def __init__(self, expr, msg):
self.expr = expr
self .msg = msg
class TransitionError(Error):
"""Lève lorsqu'une opération tente une transition d'état qui n'est pas
autorisée.
Attributs :
prev -- état au début de la transition
next -- tentative de nouvel état
msg -- explication de la raison pour laquelle la transition spécifique n'est pas autorisée
"""
def __init__(self, prev, next, msg):
self.prev = prev
self.next = next
self.msg = msg
La plupart des exceptions sont définies avec des noms qui se terminent par « Erreur », similaires au
nom des exceptions standard. La plupart des noms d'exception se terminent par « Erreur ».
De nombreux modules standards définissent leurs propres exceptions pour signaler les erreurs qui peuvent
survenir dans les fonctions qu'ils définissent. Plus d'informations sur les classes sont présentées dans
chapitre :ref:`tut-. classes`.
De nombreux modules standards définissent leurs propres exceptions pour signaler
les erreurs pouvant survenir dans les fonctions qu'ils définissent. Voir le chapitre :ref:`tut-classes` pour plus d'informations sur les classes.
.. _tut-cleanup :
Définition des actions de nettoyage Définition des actions de nettoyage
================ == ==================================
L'instruction :keyword:`try` a une autre clause facultative qui est destinée à
définir les actions de nettoyage qui doivent être exécutées en toutes circonstances. Par
exemple :
:keyword:`try`. un autre Une clause facultative dont le but est de définir une fonction
qui doit être exécutée en toutes circonstances. Par exemple : :
>>> essayez :
... augmentez KeyboardInterrupt
... enfin :
... imprimez ' Au revoir, le monde !'
...
Au revoir, le monde !
Traceback (dernier appel le plus récent) :
Fichier " KeyboardInterrupt Une *finally clause* est toujours exécutée avant de quitter l'instruction :keyword:`try` , qu'une exception ait s'est produite ou non Lorsqu'une exception s'est produite dans la clause :keyword:`try` et n'a pas été gérée par un :keyword:`sauf` (ou cela s'est produit dans une clause :keyword:`sauf` ou :keyword:`else`), il est ré-relancé après le :keyword:` La clause enfin` a a été exécutée. La clause :keyword:`finally` est également exécutée "à la sortie" quand toute autre clause de l'instruction :keyword:`try` est gauche via une instruction :keyword:`break`, :keyword:`continue` ou :keyword:`return` Un exemple plus compliqué (ayant :keyword:`sauf` et Clauses :keyword:`finally` dans la même instruction :keyword:`try` fonctionne à partir de Python 2.5) : Indépendamment du fait qu'une exception se produise ou non, la clause *finally* se termine lorsque le programme quitte :keyword:`try` sera définitivement exécuté après . Lorsqu'une exception non interceptée par :keyword:`sauf` se produit dans une instruction :keyword:`try` (ou elle se produit dans une clause :keyword:`sauf` ou :keyword:`else`), il sera renvoyé après l'exécution de la clause :keyword:`finally`. L'instruction :keyword:`try` est suivie de :keyword:`break`, :keyword:`continue` ou :keyword:`return`. L'instruction quittant exécutera également :keyword : Clause « enfin ». Voici un exemple plus complexe (le fonctionnement des clauses :keyword:`sauf` et :keyword:`finally` dans la même instruction :keyword:`try` La méthode est la même que Python 2.5) : : >>> def diviser(x, y): ... essayez: ... résultat = x / y ... sauf ZeroDivisionError : ... imprimez "division par zéro !" ... sinon : .. . Résultat ... Enfin : ... Imprimer "Exécution de la clause finale" ... & GT ;>> (2, 1) le résultat est 2 exécution de la clause finale >>> diviser(2, 0) division par zéro ! exécution de la clause final >>> Divide("2", "1") exécution de la clause final Traceback (la plupart dernier appel récent) : Fichier " Fichier " TypeError : type(s) d'opérande(s) non pris en charge pour / : 'str' et 'str' Comme vous pouvez le voir, la clause :keyword:`finally` est exécutée dans tous les cas. The : exc:`TypeError` déclenché en divisant deux chaînes n'est pas géré par la clause :keyword:`sauf` et est donc relancé après que la clause :keyword:`finally` a été exécuté. Comme vous pouvez le voir, la clause :keyword:`finally` s'exécutera dans tous les cas. :exc:`TypeError` est renvoyé lorsque deux chaînes sont divisées et n'est pas intercepté par la clause :keyword:`sauf`, donc dans :keyword:`finally` Relance après le La clause a fini de s'exécuter. Dans les applications du monde réel, la clause :keyword:`finally` est utile pour libérer des ressources externes (telles que des fichiers ou des connexions réseau), que que le l'utilisation de la ressource a réussi. Dans les applications réelles, la clause :keyword:`finally` est utilisée pour libérer des ressources externes (fichiers ou connexions réseau, etc.), indépendamment de savoir s'il y a des erreurs dans leur utilisation. .. _tut-cleanup-with : Actions de nettoyage prédéfinies Actions de nettoyage prédéfinies =============== = ======================================= Certains objets définissent un nettoyage standard -up actions à entreprendre lorsque l'objet n'est plus nécessaire, que l'opération utilisant l'objet ait réussi ou échoué. Regardez l'exemple suivant, qui tente de s'ouvrir. un fichier et imprimer son contenu à l'écran : Certains objets définissent un comportement de nettoyage standard, que l'opération sur l'objet réussisse ou non, lorsque l'objet n'est plus nécessaire Cela prendra bientôt effet. L'exemple suivant tente d'ouvrir un fichier et d'imprimer son contenu à l'écran. :: for line in open("myfile.txt"): print line Le problème avec ce code est qu'il laisse le fichier ouvert pour une durée indéterminée temps après la fin de l'exécution du code. Ce n'est pas un problème dans les scripts simples, mais peut être un problème pour les applications plus volumineuses. L'instruction with` permet d'utiliser des objets tels que des fichiers de manière à garantir qu'ils sont toujours nettoyés rapidement et correctement. Fermez les fichiers ouverts. Cela convient aux scripts simples , mais peut causer des problèmes dans des applications plus volumineuses. L'instruction :keyword:`with` permet aux objets tels que les fichiers de garantir qu'ils sont toujours nettoyés de manière rapide et précise. :: avec open("myfile.txt") comme f: for line in f: print line Une fois l'instruction exécutée, le fichier *f * est toujours fermé, même si un problème a été rencontré lors du traitement des lignes. D'autres objets qui fournissent des actions de nettoyage prédéfinies l'indiqueront dans leur documentation. Le fichier *f* est toujours fermé après l'exécution de l'instruction, même si une erreur s'est produite lors du traitement des données dans le fichier. Si d'autres objets fournissent des comportements de nettoyage prédéfinis, veuillez consulter leur documentation. Ce qui précède est le tutoriel de base de Python 2.7 : erreurs et exceptions. Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois (www.php.cn) !