Formation Python
Python imprime un traceback lorsqu'une exception est levée dans votre code. La sortie de trace peut être un peu lourde si vous la voyez pour la première fois ou si vous ne savez pas ce qu’elle vous dit. Mais le suivi Python contient une mine d'informations qui peuvent vous aider à diagnostiquer et à résoudre le motif de l'exception générée dans votre code. Comprendre les informations fournies par une trace Python est essentiel pour devenir un meilleur programmeur Python.
À la fin de ce didacticiel, vous pourrez:
- Donner un sens à la prochaine trace que vous voyez
- Reconnaître certaines des traces les plus courantes
- Enregistrer un suivi avec succès tout en maintenant l'exception
Qu'est-ce qu'un Traceback Python?
Une trace est un rapport contenant les appels de fonction effectués dans votre code à un moment donné. Les tracés sont connus sous plusieurs noms, y compris trace de la pile, trace de pile, la traceet peut-être d'autres. En Python, le terme utilisé est traceback.
Lorsque votre programme génère une exception, Python imprimera le traçage actuel pour vous aider à déterminer ce qui ne va pas. Voici un exemple pour illustrer cette situation:
# exemple.py
def saluer(Quelqu'un):
impression('Bonjour, ' + quelqu'un)
saluer('Chad')
Ici, saluer()
est appelé avec le paramètre Quelqu'un
. Cependant, dans saluer()
, ce nom de variable n’est pas utilisé. Au lieu de cela, il a été mal orthographié quelqu'un
dans le impression()
appel.
Remarque: Ce tutoriel suppose que vous comprenez les exceptions Python. Si vous n'êtes pas familier ou si vous souhaitez simplement un rafraîchissement, vous devriez consulter Exceptions Python: une introduction.
Lorsque vous exécutez ce programme, vous obtenez le suivi suivant:
$ python exemple.py
Traceback (dernier appel le plus récent):
Fichier "/path/to/example.py", ligne 4, dans
saluer ('Chad')
Fichier "/path/to/example.py", ligne 2, dans message d'accueil
print ('Bonjour', quelque chose)
NameError: le nom 'someon' n'est pas défini
Cette sortie de suivi contient toutes les informations dont vous aurez besoin pour diagnostiquer le problème. La dernière ligne de la sortie de traceback vous indique le type d'exception levée ainsi que des informations pertinentes sur cette exception. Les lignes précédentes du suivi soulignent le code qui a provoqué la levée de l'exception.
Dans la trace ci-dessus, l’exception était une NameError
, ce qui signifie qu’il y a une référence à un nom (variable, fonction, classe) qui n’a pas été défini. Dans ce cas, le nom référencé est quelqu'un
.
La dernière ligne dans ce cas contient suffisamment d'informations pour vous aider à résoudre le problème. Recherche du code pour le nom quelqu'un
, qui est une faute d’orthographe, vous orientera dans la bonne direction. Cependant, votre code est souvent beaucoup plus compliqué.
Comment lisez-vous un Traceback Python?
Le suivi Python contient de nombreuses informations utiles lorsque vous essayez de déterminer la raison d’une exception générée dans votre code. Dans cette section, vous allez parcourir différentes traces en arrière afin de comprendre les différentes informations contenues dans une trace.
Vue d'ensemble du traçage Python
Il existe plusieurs sections importantes pour chaque traceback Python. Le schéma ci-dessous met en évidence les différentes parties:
En Python, il est préférable de lire la trace de bas en haut:
-
Boite bleue: La dernière ligne de la trace est la ligne du message d'erreur. Il contient le nom de l'exception qui a été levée.
-
Boîte verte: Après le nom de l'exception est le message d'erreur. Ce message contient généralement des informations utiles pour comprendre la raison de la levée de l'exception.
-
Boîte jaune: Plus haut dans la trace, les différents appels de fonction se déplacent de bas en haut, du plus récent au moins récent. Ces appels sont représentés par des entrées de deux lignes pour chaque appel. La première ligne de chaque appel contient des informations telles que le nom du fichier, le numéro de la ligne et le nom du module, spécifiant toutes où le code peut être trouvé.
-
Souligné en rouge: La deuxième ligne de ces appels contient le code qui a été exécuté.
Il existe quelques différences entre la sortie de traceback lorsque vous exécutez votre code dans la ligne de commande et le code en cours d’exécution dans la réplique. Ci-dessous se trouve le même code de la section précédente exécutée dans un REPL et la sortie de trace résultante:
>>> def saluer(Quelqu'un):
... impression('Bonjour, ' + quelqu'un)
...
>>> saluer('Chad')
Traceback (dernier appel le plus récent):
Fichier "" , ligne 1, dans
Fichier "" , ligne 2, dans saluer
NameError: le nom 'quelqu'un' n'est pas défini
Notez qu'au lieu de noms de fichiers, vous obtenez "
. Cela a du sens puisque vous avez saisi le code via une entrée standard. En outre, les lignes de code exécutées ne sont pas affichées dans le suivi.
RemarqueRemarque: Si vous avez l'habitude de voir des traces de pile dans d'autres langages de programmation, vous remarquerez une différence majeure dans l'apparence d'une trace Python en comparaison. La plupart des autres langues affichent l'exception en haut, puis les appels les plus récents aux moins récents.
Cela a déjà été dit, mais juste pour répéter, une trace de Python devrait être lue de bas en haut. Ceci est très utile car le suivi est imprimé et votre terminal (ou où que vous lisiez le suivi) se retrouve généralement au bas de la sortie, ce qui vous donne l'endroit idéal pour commencer à lire le suivi.
Procédure pas à pas spécifique
Le fait de parcourir certaines sorties de traceback vous aidera à mieux comprendre et à voir quelles informations le traceback vous donnera.
Le code ci-dessous est utilisé dans les exemples suivants pour illustrer les informations fournies par un suivi Python:
# greetings.py
def who_to_greet(la personne):
revenir la personne si la personne autre contribution('Salut à qui? ')
def saluer(Quelqu'un, salutation='Bonjour'):
impression(salutation + ',' + who_to_greet(Quelqu'un))
def salut_many(personnes):
pour la personne dans personnes:
essayer:
saluer(la personne)
sauf Exception:
impression('salut, ' + la personne)
Ici, who_to_greet ()
prend une valeur, la personne
, et le renvoie ou invite une valeur à renvoyer à la place.
Ensuite, saluer()
prend un nom pour être salué, Quelqu'un
et une option salutation
valeur et appels impression()
. who_to_greet ()
est aussi appelé avec le Quelqu'un
valeur transmise.
Finalement, greet_many ()
ira sur la liste des personnes
et appeler saluer()
. Si une exception est déclenchée en appelant saluer()
, un simple message d'accueil de sauvegarde est alors imprimé.
Ce code ne contient aucun bogue susceptible de générer une exception tant que la bonne entrée est fournie.
Si vous ajoutez un appel à saluer()
au fond de salutations.py
et spécifiez un argument de mot-clé inattendu (par exemple, saluer ('Chad', greting = 'Yo')
), vous obtiendrez le suivi suivant:
$ python exemple.py
Traceback (dernier appel le plus récent):
Fichier "/path/to/greetings.py", ligne 19, dans
saluer ('Chad', greting = 'Yo')
TypeError: greet () a un argument de mot clé inattendu 'greting'
Une fois encore, avec un suivi Python, il est préférable de revenir en arrière, en remontant la sortie. À partir de la dernière ligne du traçage, vous pouvez voir que l’exception était une Erreur-type
. Les messages qui suivent le type d'exception, tout ce qui suit le côlon, vous fournissent d'excellentes informations. Il vous dit que saluer()
a été appelé avec un argument de mot-clé auquel il ne s’attendait pas. Le nom de l'argument inconnu vous est également donné: greting
.
En montant, vous pouvez voir la ligne qui a abouti à l'exception. Dans ce cas, c’est le saluer()
appelons cela, nous avons ajouté au bas de salutations.py
.
La ligne suivante vous indique le chemin d'accès au fichier contenant le code, le numéro de la ligne où ce code peut être trouvé et le module dans lequel il se trouve. Dans ce cas, notre code n'utilise aucun autre module Python. , on vient de voir
ici, ce qui signifie que c'est le fichier en cours d'exécution.
Avec un fichier différent et une entrée différente, vous pouvez voir le traçage vous orienter vraiment dans la bonne direction pour trouver le problème. Si vous suivez, supprimez le buggy saluer()
appel du bas de salutations.py
et ajoutez le fichier suivant à votre répertoire:
# exemple.py
de salutations importation saluer
saluer(1)
Ici vous avez configuré un autre fichier Python qui importe votre module précédent, salutations.py
et en utilisant saluer()
à partir de cela. Voici ce qui se passe si vous exécutez maintenant exemple.py
:
$ python exemple.py
Traceback (dernier appel le plus récent):
Fichier "/path/to/example.py", ligne 3, dans
saluer (1)
Fichier "/path/to/greetings.py", ligne 5, dans message d'accueil
print (salutation + ',' + who_to_greet (quelqu'un))
TypeError: doit être str, pas int
L'exception soulevée dans ce cas est un Erreur-type
encore une fois, mais cette fois le message est un peu moins utile. Il vous dit que quelque part dans le code, il s'attendait à travailler avec une chaîne, mais un entier a été donné.
En montant, vous voyez la ligne de code qui a été exécutée. Puis le fichier et le numéro de ligne du code. Cette fois, cependant, au lieu de
, nous obtenons le nom de la fonction en cours d'exécution, saluer()
.
En passant à la prochaine ligne de code exécutée, nous voyons notre problématique saluer()
appel passant dans un entier.
Parfois, après la levée d'une exception, un autre morceau de code intercepte cette exception et génère également une exception. Dans ces situations, Python générera tous les retraits d’exception dans l’ordre dans lequel ils ont été reçus, se terminant à nouveau par le dernier retraçage de l’exception.
Comme cela peut être un peu déroutant, voici un exemple. Ajouter un appel à greet_many ()
au fond de salutations.py
:
# greetings.py
...
salut_many([[[['Chad', 'Dan', 1])
Cela devrait donner lieu à des salutations aux trois personnes. Toutefois, si vous exécutez ce code, vous verrez un exemple de plusieurs retraits de trace en cours de sortie:
$ python salutations.py
Bonjour tchad
Bonjour Dan
Traceback (dernier appel le plus récent):
Fichier "greetings.py", ligne 10, dans greet_many
saluer (personne)
Fichier "greetings.py", ligne 5, dans greet
print (salutation + ',' + who_to_greet (quelqu'un))
TypeError: doit être str, pas int
Lors du traitement de l'exception ci-dessus, une autre exception s'est produite:
Traceback (dernier appel le plus récent):
Fichier "greetings.py", ligne 14, dans
greet_many (['Chad', 'Dan', 1])
Fichier "greetings.py", ligne 12, dans greet_many
print ('salut' + personne)
TypeError: doit être str, pas int
Notez la ligne en surbrillance commençant par Pendant la manutention
dans la sortie ci-dessus. Entre toutes les traces, vous verrez cette ligne. Son message est très clair, alors que votre code essayait de gérer l’exception précédente, une autre exception était levée.
Remarque: La fonctionnalité d’affichage des retraits des exceptions précédentes de Python a été ajoutée à Python 3. En Python 2, vous n’obtenez que le traçage de la dernière exception.
Vous avez déjà vu l’exception précédente lorsque vous avez appelé saluer()
avec un entier. Depuis que nous avons ajouté un 1
à la liste des personnes à saluer, on peut s'attendre au même résultat. Cependant, la fonction greet_many ()
enveloppe le saluer()
appeler dans un essayer
et sauf
bloc. Au cas où saluer()
résulte en une exception levée, greet_many ()
veut imprimer un message d'accueil par défaut.
La partie pertinente de salutations.py
est répété ici:
def salut_many(personnes):
pour la personne dans personnes:
essayer:
saluer(la personne)
sauf Exception:
impression('salut, ' + la personne)
Donc quand saluer()
résultats dans le Erreur-type
à cause de la mauvaise entrée entière, greet_many ()
gère cette exception et tente d’imprimer un message d'accueil simple. Ici, le code aboutit à une autre exception similaire. Il tente toujours d’ajouter une chaîne et un entier.
Voir toute la sortie de traceback peut vous aider à voir quelle peut être la cause réelle d'une exception. Parfois, lorsque vous voyez la dernière exception déclenchée et son suivi, vous ne pouvez toujours pas voir ce qui ne va pas. Dans ces cas, le passage aux exceptions précédentes vous donne généralement une meilleure idée de la cause première.
Quels sont les traçages courants en Python?
Savoir comment lire une trace Python lorsque votre programme lève une exception peut être très utile lorsque vous programmez, mais connaître certaines des traces les plus courantes peut également accélérer votre processus.
Voici quelques exceptions courantes que vous pourriez rencontrer, les raisons pour lesquelles elles ont été soulevées, leur signification et les informations que vous pouvez trouver dans leurs retraits.
AttributeError
le AttributeError
est déclenchée lorsque vous essayez d'accéder à un attribut sur un objet pour lequel cet attribut n'a pas été défini. La documentation Python définit le moment où cette exception est déclenchée:
Relevé lorsqu'une référence d'attribut ou une attribution échoue. (La source)
Voici un exemple de AttributeError
être élevé:
>>> an_int = 1
>>> an_int.un_attribut
Traceback (dernier appel le plus récent):
Fichier "" , ligne 1, dans
AttributeError: L'objet 'int' n'a pas d'attribut 'an_attribute'
La ligne de message d'erreur pour un AttributeError
vous indique que le type d'objet spécifique, int
dans ce cas, l’attribut n’a pas été accédé, un_attribut
dans ce cas. Voyant le AttributeError
dans la ligne de message d'erreur peut vous aider à identifier rapidement l'attribut auquel vous avez tenté d'accéder et où aller pour le corriger.
Généralement, obtenir cette exception indique que vous travaillez probablement avec un objet d'un type différent de celui que vous attendiez:
>>> une liste = (1, 2)
>>> une liste.ajouter(3)
Traceback (dernier appel le plus récent):
Fichier "" , ligne 1, dans
AttributeError: L'objet 'tuple' n'a pas d'attribut 'append'
Dans l'exemple ci-dessus, vous pourriez vous attendre à une liste
être de type liste
, qui a une méthode appelée .ajouter()
. Quand vous recevez le AttributeError
exception et voir qu'il a été soulevé lorsque vous essayez d'appeler .ajouter()
, cela vous indique que vous n’avez probablement pas affaire au type d’objet que vous attendiez.
Cela se produit souvent lorsque vous vous attendez à ce qu'un objet renvoyé par un appel de fonction ou de méthode soit d'un type spécifique et que vous vous retrouviez avec un objet de type. Aucun
. Dans ce cas, la ligne du message d'erreur sera lue, AttributeError: l'objet 'NoneType' n'a pas d'attribut 'append'
.
ImportError
le ImportError
est levé quand quelque chose ne va pas avec une déclaration d'importation. Vous obtiendrez cette exception, ou sa sous-classe ModuleNotFoundError
si le module que vous essayez d’importer est introuvable ou si vous essayez d’importer quelque chose d’un module qui n’existe pas dans le module. La documentation Python définit le moment où cette exception est déclenchée:
Relevé lorsque l'instruction d'importation rencontre des difficultés lors du chargement d'un module. Également soulevé lorsque le «à partir de la liste» dans
de ... import
a un nom qui ne peut pas être trouvé. (La source)
Voici un exemple de ImportError
et ModuleNotFoundError
être élevé:
>>> importation asdf
Traceback (dernier appel le plus récent):
Fichier "" , ligne 1, dans
ModuleNotFoundError: Aucun module nommé 'asdf'
>>> de collections importation asdf
Traceback (dernier appel le plus récent):
Fichier "" , ligne 1, dans
ImportError: ne peut pas importer le nom 'asdf'
Dans l'exemple ci-dessus, vous pouvez voir que tenter d'importer un module qui n'existe pas, asdf
, résultats dans le ModuleNotFoundError
. Lorsqu’on tente d’importer quelque chose qui n’existe pas, asdf
, à partir d'un module qui existe, collections
, il en résulte une ImportError
. Les lignes de message d’erreur au bas de la trace vous indiquent ce qui ne peut pas être importé, asdf
dans les deux cas.
IndexError
le IndexError
est levé lorsque vous essayez de récupérer un index à partir d'une séquence, comme un liste
ou un tuple
et l’index ne figure pas dans la séquence. La documentation Python définit le moment où cette exception est déclenchée:
Relevé lorsqu'un indice de séquence est hors limites. (La source)
Voici un exemple qui soulève la IndexError
:
>>> une liste = [[[['une', 'b']
>>> une liste[[[[3]
Traceback (dernier appel le plus récent):
Fichier "" , ligne 1, dans
IndexError: index de liste hors de portée
La ligne de message d'erreur pour un IndexError
ne vous donne pas d'excellentes informations. Vous pouvez voir que vous avez une référence de séquence qui est hors de portée
et quel est le type de la séquence, un liste
dans ce cas. Ces informations, associées au reste de la trace, sont généralement suffisantes pour vous aider à identifier rapidement comment résoudre le problème.
KeyError
Semblable à la IndexError
, la KeyError
est déclenchée lorsque vous essayez d’accéder à une clé qui ne figure pas dans le mappage, généralement une clé. dict
. Pensez à cela comme à la IndexError
mais pour les dictionnaires. La documentation Python définit le moment où cette exception est déclenchée:
Relevé lorsqu'une clé de mappage (dictionnaire) est introuvable dans l'ensemble de clés existantes. (La source)
Voici un exemple de KeyError
être élevé:
>>> un_dict[[[['b']
Traceback (dernier appel le plus récent):
Fichier "" , ligne 1, dans
KeyError: 'b'
La ligne de message d'erreur pour un KeyError
vous donne la clé qui n'a pas pu être trouvée. Ce n’est pas grand-chose à faire, mais, combiné avec le reste de la trace, suffit généralement à résoudre le problème.
Pour un regard en profondeur sur KeyError
, consultez les exceptions Python KeyError et Comment les gérer.
NameError
le NameError
est déclenché lorsque vous avez référencé une variable, un module, une classe, une fonction ou un autre nom qui n’a pas été défini dans votre code. La documentation Python définit le moment où cette exception est déclenchée:
Relevé lorsqu'un nom local ou global n'est pas trouvé. (La source)
Dans le code ci-dessous, saluer()
prend un paramètre la personne
. Mais dans la fonction elle-même, ce paramètre a été mal orthographié persn
:
>>> def saluer(la personne):
... impression(F'Bonjour, persn')
>>> saluer('Monde')
Traceback (dernier appel le plus récent):
Fichier "" , ligne 1, dans
Fichier "" , ligne 2, dans saluer
NameError: nom 'persn' n'est pas défini
La ligne de message d'erreur du NameError
traceback vous donne le nom qui manque. Dans l'exemple ci-dessus, il s'agit d'une variable ou d'un paramètre mal orthographié pour la fonction transmise.
UNE NameError
sera également levé si c’est le paramètre que vous avez mal orthographié:
>>> def saluer(persn):
... impression(F'Bonjour, la personne')
>>> saluer('Monde')
Traceback (dernier appel le plus récent):
Fichier "" , ligne 1, dans
Fichier "" , ligne 2, dans saluer
NameError: nom 'personne' n'est pas défini
Ici, on pourrait croire que vous n’avez rien fait de mal. La dernière ligne exécutée et référencée dans le suivi semble bonne. Si vous vous trouvez dans cette situation, vous devez alors regarder dans votre code pour savoir où la personne
la variable est utilisée et définie. Ici, vous pouvez rapidement voir que le nom du paramètre a été mal orthographié.
Erreur de syntaxe
le Erreur de syntaxe
est déclenché lorsque vous avez une syntaxe Python incorrecte dans votre code. La documentation Python définit le moment où cette exception est déclenchée:
Lancé lorsque l'analyseur rencontre une erreur de syntaxe. (La source)
Ci-dessous, le problème est un colon manquant qui devrait se trouver à la fin de la ligne de définition de la fonction. Dans le REPL Python, cette erreur de syntaxe est immédiatement générée après avoir tapé, entrez:
>>> def saluer(la personne)
Fichier "" , ligne 1
def saluer(la personne)
^
Erreur de syntaxe: Syntaxe invalide
La ligne de message d'erreur du Erreur de syntaxe
vous dit seulement qu'il y avait un problème avec la syntaxe de votre code. En regardant dans les lignes ci-dessus, vous voyez la ligne avec le problème et généralement un ^
(Caret) montrant le point du problème. Ici, le côlon est absent de la fonction def
déclaration.
Aussi, avec Erreur de syntaxe
tracebacks, la première ligne régulière Traceback (dernier appel le plus récent):
est manquant. C'est parce que le Erreur de syntaxe
est levé lorsque Python tente d’analyser votre code et que les lignes ne sont pas en cours d’exécution.
Erreur-type
le Erreur-type
est déclenchée lorsque votre code tente de faire quelque chose avec un objet qui ne peut pas le faire, comme essayer d’ajouter une chaîne à un entier ou d’appeler len ()
sur un objet où sa longueur n’est pas définie. La documentation Python définit le moment où cette exception est déclenchée:
Relevé lorsqu'une opération ou une fonction est appliquée à un objet de type inapproprié. (La source)
Voici plusieurs exemples de Erreur-type
être élevé:
>>> 1 + '1'
Traceback (dernier appel le plus récent):
Fichier "" , ligne 1, dans
Erreur-type: type (s) d'opérande non pris en charge pour +: 'int' et 'str'
>>> '1' + 1
Traceback (dernier appel le plus récent):
Fichier "" , ligne 1, dans
Erreur-type: doit être str, pas int
>>> len(1)
Traceback (dernier appel le plus récent):
Fichier "" , ligne 1, dans
Erreur-type: l'objet de type 'int' n'a pas de len ()
Tous les exemples ci-dessus d’élever un Erreur-type
résulte en une ligne de message d'erreur avec des messages différents. Chacun d'eux fait un très bon travail pour vous informer de ce qui ne va pas.
Les deux premiers exemples tentent d'ajouter des chaînes et des entiers. Cependant, ils sont légèrement différents:
- Le premier essaie d’ajouter un
str
à unint
. - La seconde tente d’ajouter un
int
à unstr
.
Les lignes de message d'erreur reflètent ces différences.
Le dernier exemple tente d'appeler len ()
sur un int
. Le message d'erreur vous indique que vous ne pouvez pas le faire avec un int
.
ValueError
le ValueError
est levé lorsque la valeur de l'objet n'est pas correcte. Vous pouvez penser à cela comme un IndexError
est élevé car la valeur de l’index n’est pas dans la plage de la séquence, seule la valeur ValueError
est pour un cas plus générique. La documentation Python définit le moment où cette exception est déclenchée:
Lancé lorsqu'une opération ou une fonction reçoit un argument qui a le bon type, mais une valeur inappropriée, et la situation n'est pas décrite par une exception plus précise, telle que
IndexError
. (La source)
Voici deux exemples de ValueError
être élevé:
>>> une, b, c = [[[[1, 2]
Traceback (dernier appel le plus récent):
Fichier "" , ligne 1, dans
ValueError: pas assez de valeurs pour décompresser (attendu 3, 2)
>>> une, b = [[[[1, 2, 3]
Traceback (dernier appel le plus récent):
Fichier "" , ligne 1, dans
ValueError: trop de valeurs à décompresser (attendu 2)
le ValueError
La ligne de message d'erreur dans ces exemples vous indique exactement quel est le problème avec les valeurs:
-
Dans le premier exemple, vous essayez de décompresser trop de valeurs. La ligne de message d'erreur vous indique même que vous vous attendiez à décompresser 3 valeurs mais 2 valeurs.
-
Dans le deuxième exemple, le problème est que vous obtenez trop de valeurs et pas assez de variables pour les décompresser.
Comment vous enregistrez un traçage?
L'obtention d'une exception et de son suivi Python résultant signifie que vous devez décider quoi faire à ce sujet. La correction de votre code est généralement la première étape, mais parfois le problème provient d'une saisie inattendue ou incorrecte. Bien qu'il soit bon de prévoir ces situations dans votre code, il est également parfois judicieux de faire taire ou de masquer l'exception en enregistrant le suivi et en faisant autre chose.
Voici un exemple de code plus réel qui doit faire taire certaines traces de retour Python. Cet exemple utilise le demandes
bibliothèque. Vous pouvez en savoir plus à ce sujet dans la bibliothèque de requêtes de Python (Guide):
# urlcaller.py
importation sys
importation demandes
réponse = demandes.obtenir(sys.argv[[[[1])
impression(réponse.status_code, réponse.contenu)
Ce code fonctionne bien. Lorsque vous exécutez ce script en lui attribuant une URL sous forme d'argument de ligne de commande, il appelle l'URL, puis imprime le code d'état HTTP et le contenu de la réponse. Cela fonctionne même si la réponse était un statut d'erreur HTTP:
$ python urlcaller.py https://httpbin.org/status/200
200 b ''
$ python urlcaller.py https://httpbin.org/status/500
500 b ''
Cependant, il arrive parfois que l’URL que votre script doit récupérer n’existe pas ou que le serveur hôte soit en panne. Dans ces cas, ce script va maintenant soulever un problème Erreur de connexion
exception et imprimer une traceback:
$ python urlcaller.py http://thisurlprobablydoesntexist.com
...
Lors du traitement de l'exception ci-dessus, une autre exception s'est produite:
Traceback (dernier appel le plus récent):
Fichier "urlcaller.py", ligne 5, dans
réponse = demandes.obtenir(sys.argv[[[[1])
Fichier "/path/to/requests/api.py", ligne 75, dans obtenir
revenir demande('obtenir', url, params=params, **Kwargs)
Fichier "/path/to/requests/api.py", ligne 60, dans demande
revenir session.demande(méthode=méthode, url=url, **Kwargs)
Fichier "/path/to/requests/sessions.py", ligne 533, dans demande
resp = soi.envoyer(préparation, **send_kwargs)
Fichier "/path/to/requests/sessions.py", ligne 646, dans envoyer
r = adaptateur.envoyer(demande, **Kwargs)
Fichier "/path/to/requests/adapters.py", ligne 516, dans envoyer
élever Erreur de connexion(e, demande=demande)
requests.exceptions.ConnectionError: HTTPConnectionPool (host = 'thisurlprobablydoesntexist.com', port = 80): Nombre maximal de nouvelles tentatives dépassé avec l'URL: / (provoqué par NewConnectionError (': Impossible d'établir une nouvelle connexion: [Errno -2] Nom ou service non connu ',))
Le traceback Python peut être très long, avec beaucoup d’autres exceptions levées et aboutissant finalement à la Erreur de connexion
être élevé par demandes
lui-même. Si vous remontez le dernier retraçage des exceptions, vous pouvez voir que le problème a commencé dans notre code avec la ligne 5 de urlcaller.py
.
Si vous emballez la ligne incriminée dans un essayer
et sauf
block, attraper l'exception appropriée permettra à votre script de continuer à fonctionner avec plus d'entrées:
# urlcaller.py
...
essayer
réponse = demandes.obtenir(sys.argv[[[[1])
sauf demandes.exceptions.Erreur de connexion:
impression(-1, 'Erreur de connexion')
autre:
impression(réponse.status_code, réponse.contenu)
Le code ci-dessus utilise un autre
clause avec le essayer
et sauf
bloc. Si vous ne connaissez pas cette fonctionnalité de Python, consultez la section sur la autre
clause dans Python Exceptions: An Introduction.
Maintenant, lorsque vous exécutez le script avec une URL qui entraînera une Erreur de connexion
être élevé, vous aurez imprimé un -1
pour le code d'état et le contenu Erreur de connexion
:
$ python urlcaller.py http://thisurlprobablydoesntexist.com
-1 erreur de connexion
Cela fonctionne très bien. Cependant, dans la plupart des systèmes réels, vous ne souhaitez pas simplement faire taire l'exception et la trace résultante, mais vous souhaitez consigner la trace. La journalisation des traces vous permet de mieux comprendre ce qui ne va pas dans vos programmes.
Vous pouvez enregistrer le suivi dans le script en important le enregistrement
package, obtenir un enregistreur et appeler .exception()
sur cet enregistreur dans le sauf
partie de la essayer
et sauf
bloc. Votre script final devrait ressembler au code suivant:
# urlcaller.py
importation enregistrement
importation sys
importation demandes
enregistreur = enregistrement.getLogger(__prénom__)
essayer:
réponse = demandes.obtenir(sys.argv[[[[1])
sauf demandes.exceptions.Erreur de connexion comme e:
enregistreur.exception()
impression(-1, 'Erreur de connexion')
autre:
impression(réponse.status_code, réponse.contenu)
Maintenant, lorsque vous exécutez le script pour une URL problématique, il imprimera le résultat attendu. -1
et Erreur de connexion
, mais cela enregistrera également le suivi:
$ python urlcaller.py http://thisurlprobablydoesntexist.com
...
Fichier "/path/to/requests/adapters.py", ligne 516, dans envoyer
élever Erreur de connexion(e, demande=demande)
requests.exceptions.ConnectionError: HTTPConnectionPool (host = 'thisurlprobablydoesntexist.com', port = 80): Nombre maximal de nouvelles tentatives dépassé avec l'URL: / (provoqué par NewConnectionError (': Impossible d'établir une nouvelle connexion: [Errno -2] Nom ou service non connu ',))
-1 erreur de connexion
Par défaut, Python enverra les messages de journal à l'erreur standard (stderr
). On dirait que nous n’avons pas du tout supprimé la sortie de trace. Toutefois, si vous appelez à nouveau tout en redirigeant le stderr
, vous pouvez voir que le système de journalisation fonctionne et que nous pouvons sauvegarder nos journaux pour plus tard:
$ python urlcaller.py http://thisurlprobablydoesntexist.com 2> mon-logs.log
-1 erreur de connexion
Conclusion
Le suivi Python contient d'excellentes informations qui peuvent vous aider à trouver ce qui ne va pas dans votre code Python. Ces retraits peuvent sembler un peu intimidants, mais une fois que vous avez analysé ce que vous essayez de vous montrer, ils peuvent être extrêmement utiles. En parcourant quelques traces en arrière, ligne par ligne, vous comprendrez mieux les informations qu’elles contiennent et vous en tirerez le meilleur parti.
Obtenir une sortie de trace Python lorsque vous exécutez votre code est une opportunité d'améliorer votre code. C’est l’une des façons dont Python essaie de vous aider.
Maintenant que vous savez comment lire un suivi Python, vous pouvez en apprendre davantage sur certains outils et techniques permettant de diagnostiquer les problèmes signalés par la sortie de votre suivi. Intégré de Python traceback
module peut être utilisé pour travailler avec et inspecter les retraits. le traceback
module peut être utile lorsque vous avez besoin de tirer davantage de la sortie de traceback. Il serait également utile d’en savoir plus sur certaines techniques de débogage de votre code Python.
[ad_2]