Exceptions KeyError Python et comment les gérer – Real Python

By | avril 24, 2019

trouver un expert Python

Python KeyError exception est une exception commune rencontrée par les débutants. Savoir pourquoi KeyError peuvent être soulevées et certaines solutions pour l’empêcher d’arrêter votre programme sont des étapes essentielles pour l’amélioration en tant que programmeur Python.

À la fin de ce tutoriel, vous saurez:

  • Quel python KeyError signifie généralement
  • Où d'autre pourriez-vous voir un KeyError dans la bibliothèque standard
  • Comment gérer un KeyError quand tu le vois

Quel python KeyError Signifie généralement

Un python KeyError exception est ce qui est déclenché lorsque vous essayez d’accéder à une clé qui n’est pas dans un dictionnaire (dict).

La documentation officielle de Python indique que le KeyError est déclenchée lorsqu’une clé de mappage est utilisée et n’est pas trouvée dans le mappage. Un mappage est une structure de données qui mappe un ensemble de valeurs à un autre. Le mappage le plus courant en Python est le dictionnaire.

Le python KeyError est un type de LookupError exception et indique qu’un problème est survenu lors de la récupération de la clé recherchée. Quand tu vois un KeyError, la signification sémantique est que la clé recherchée est introuvable.

Dans l'exemple ci-dessous, vous pouvez voir un dictionnaire (âge) définis avec l’âge de trois personnes. Lorsque vous essayez d’accéder à une clé qui ne figure pas dans le dictionnaire, un KeyError est élevé:

>>>

>>> âge = 'Jim': 30, 'Pam': 28, 'Kevin': 33
>>> âge[[[['Michael']
Traceback (dernier appel le plus récent):
  Fichier "", ligne 1, dans 
KeyError: 'Michael'

Ici, tentative d'accès à la clé 'Michael' dans le âge résultats du dictionnaire dans un KeyError être élevé. Au bas de la trace, vous obtenez les informations pertinentes:

  • Le fait qu'un KeyError a été soulevée
  • La clé qui n’a pas pu être trouvée, qui était 'Michael'

L'avant-dernière ligne vous indique quelle ligne a généré l'exception. Ces informations sont plus utiles lorsque vous exécutez du code Python à partir d'un fichier.

Dans le programme ci-dessous, vous pouvez voir le âge dictionnaire défini à nouveau. Cette fois-ci, vous serez invité à fournir le nom de la personne à récupérer pour:

    1 # ages.py
    2 
    3 âge = 'Jim': 30, 'Pam': 28, 'Kevin': 33
    4 la personne = contribution('Obtenir l'âge pour:')
    5 impression(F'la personne    est âge[person]    ans.')

Ce code prendra le nom que vous avez fourni à l'invite et tentera de récupérer l'âge de cette personne. Tout ce que vous tapez à l’invite sera utilisé comme clé de la âge dictionnaire, ligne 4.

En reprenant l'exemple d'échec présenté ci-dessus, nous obtenons une autre trace, cette fois avec des informations sur la ligne du fichier que le KeyError est issu de:

$ python ages.py
Obtenir l'âge pour: Michael
Traceback (dernier appel le plus récent):
Fichier "ages.py", ligne 4, dans 
        print (f 'personne est âges[person] ans.')
KeyError: 'Michael'

Le programme échoue lorsque vous donnez une clé qui ne figure pas dans le dictionnaire. Ici, les dernières lignes du traçage soulignent le problème. Fichier "ages.py", ligne 4, dans vous indique quelle ligne de quel fichier a généré le résultat KeyError exception. Ensuite, vous êtes montré cette ligne. Finalement, le KeyError exception fournit la clé manquante.

Donc vous pouvez voir que le KeyError La dernière ligne de traceback ne vous fournit pas assez d’informations, mais les lignes qui précèdent peuvent vous aider à comprendre ce qui ne va pas.

Où d'autre pouvez-vous voir un python KeyError dans la bibliothèque standard

La grande majorité du temps, un Python KeyError est déclenchée car aucune clé ne figure dans un dictionnaire ou une sous-classe de dictionnaire (telle que os.environ).

Dans de rares cas, vous pouvez également le voir apparaître dans d’autres endroits de la bibliothèque standard de Python, comme dans le répertoire. fichier zip module, si un élément n’est pas trouvé dans une archive ZIP. Cependant, ces lieux conservent la même signification sémantique du Python KeyError, ce qui ne trouve pas la clé demandée.

Dans l'exemple suivant, vous pouvez voir en utilisant le zipfile.ZipFile classe pour extraire des informations sur une archive ZIP en utilisant .getinfo ():

>>>

>>> de fichier zip importation Fichier zip
>>> fichier zip = Fichier zip('the_zip_file.zip')
>>> fichier zip.getinfo('quelque chose')
Traceback (dernier appel le plus récent):
Fichier "", ligne 1, dans 
Fichier "/path/to/python/installation/zipfile.py", ligne 1304, dans getinfo
        'Il n'y a pas d'élément nommé% r dans l'archive'% name)
KeyError: "Il n'y a aucun élément nommé 'quelque chose' dans l'archive"

Cela ne ressemble pas vraiment à une recherche de clé dans le dictionnaire. Au lieu de cela, c'est un appel à zipfile.ZipFile.getinfo () cela soulève l'exception.

Le traçage est également un peu différent avec un peu plus d'informations fournies que la clé manquante: KeyError: "Il n'y a aucun élément nommé 'quelque chose' dans l'archive".

La dernière chose à noter ici est que la ligne qui a soulevé la KeyError n'est pas dans votre code. C'est dans le fichier zip code, mais les lignes précédentes de la trace indiquent quelles lignes de votre code ont causé le problème.

Quand vous devez élever un python KeyError dans votre propre code

Il se peut qu’il soit logique que vous éleviez un Python. KeyError exception dans votre propre code. Cela peut être fait en utilisant le élever mot-clé et appeler le KeyError exception:

Habituellement, le message serait la clé manquante. Cependant, comme dans le cas du fichier zip package, vous pouvez choisir de donner un peu plus d’informations pour aider le prochain développeur à mieux comprendre ce qui ne va pas.

Si vous décidez d'élever un python KeyError dans votre propre code, assurez-vous que votre cas d'utilisation correspond à la signification sémantique derrière l'exception. Cela devrait indiquer que la clé recherchée est introuvable.

Comment manipuler un python KeyError Quand tu le vois

Lorsque vous rencontrez un KeyError, il existe quelques moyens standard de le gérer. Selon votre cas d'utilisation, certaines de ces solutions pourraient être meilleures que d'autres. Le but ultime est d'arrêter les imprévus KeyError les exceptions d'être soulevées.

La solution habituelle: .obtenir()

Si la KeyError est généré à partir d'une recherche de clé de dictionnaire ayant échoué dans votre propre code, vous pouvez utiliser .obtenir() pour retourner soit la valeur trouvée à la clé spécifiée, soit une valeur par défaut.

Comme dans l'exemple de récupération d'âge, l'exemple suivant montre un meilleur moyen d'obtenir l'âge du dictionnaire à l'aide de la clé fournie à l'invite:

    1 # ages.py
    2 
    3 âge = 'Jim': 30, 'Pam': 28, 'Kevin': 33
    4 la personne = contribution('Obtenir l'âge pour:')
    5 âge = âge.obtenir(la personne)
    6 
    7 si âge:
    8     impression(F'la personne    est âge    ans.')
    9 autre:
dix     impression(F"la personnel'âge de est inconnu. ")

Ici, la ligne 5 montre comment vous pouvez obtenir la valeur d’âge de âge en utilisant .obtenir(). Cela entraînera la âge variable ayant la valeur d'âge trouvée dans le dictionnaire pour la clé fournie ou une valeur par défaut, Aucun dans ce cas.

Cette fois, vous ne recevrez pas un KeyError exception soulevée en raison de l'utilisation de la plus sûre .obtenir() méthode pour obtenir l'âge plutôt que d'essayer d'accéder directement à la clé:

$ python ages.py
Obtenir l'âge pour: Michael
L'âge de Michael est inconnu.

Dans l’exemple d’exécution ci-dessus, le KeyError n'est plus levé lorsqu'une mauvaise clé est fournie. La clé 'Michael' ne se trouve pas dans le dictionnaire, mais en utilisant .obtenir(), nous obtenons un Aucun retourné plutôt qu'un soulevé KeyError.

le âge variable aura soit l’âge de la personne qui se trouve dans le dictionnaire, soit la valeur par défaut (Aucun par défaut). Vous pouvez également spécifier une valeur par défaut différente dans .obtenir() appeler en passant un deuxième argument ou le mot-clé argument défaut.

C'est la ligne 5 de l'exemple ci-dessus avec un âge par défaut différent spécifié à l'aide de .obtenir():

âge = âge.obtenir(la personne, défaut=0)

Ici, au lieu de 'Michael' rentrant Aucun, ça reviendrait 0 car la clé n’a pas été trouvée et que la valeur par défaut à renvoyer est maintenant 0.

La solution rare: vérifier les clés

Il est parfois nécessaire de déterminer l’existence d’une clé dans un dictionnaire. Dans ces cas, en utilisant .obtenir() pourrait ne pas vous donner les informations correctes. Obtenir un Aucun est revenu d'un appel à .obtenir() pourrait signifier que la clé n'a pas été trouvée ou que la valeur trouvée à la clé dans le dictionnaire est en réalité Aucun.

Avec un dictionnaire ou un objet de type dictionnaire, vous pouvez utiliser le dans opérateur pour déterminer si une clé est dans le mappage. Cet opérateur retournera un booléen (Vrai ou Faux) valeur indiquant si la clé est trouvée dans le dictionnaire.

Dans cet exemple, vous obtenez un réponse dictionnaire d'appeler une API. Cette réponse pourrait avoir un Erreur valeur de clé définie dans la réponse, qui indiquerait que la réponse est dans un état d'erreur:

    1 # parse_api_response.py
    2 ...
    3 # En supposant que vous ayez reçu une `réponse` en appelant une API qui pourrait
    4 # avoir une clé d'erreur dans la `réponse` si quelque chose s'est mal passé
    5 
    6 si 'Erreur' dans réponse:
    7     ...  # Analyser l'état d'erreur
    8 autre:
    9     ...  # Analyser l'état de réussite

Ici, il y a une différence dans la vérification pour voir si le Erreur la clé existe dans le réponse et obtenir une valeur par défaut de la clé. Il s'agit d'un cas rare où vous recherchez réellement si la clé est dans le dictionnaire et non quelle est la valeur de cette clé.

La solution générale: essayer sauf

Comme pour toute exception, vous pouvez toujours utiliser le essayer sauf bloquer pour isoler le code susceptible de générer une exception et fournir une solution de sauvegarde.

Vous pouvez utiliser le essayer sauf bloquer dans un exemple similaire au précédent, mais cette fois en fournissant un message par défaut à imprimer KeyError être soulevé dans le cas normal:

    1 # ages.py
    2 
    3 âge = 'Jim': 30, 'Pam': 28, 'Kevin': 33
    4 la personne = contribution('Obtenir l'âge pour:')
    5 
    6 essayer:
    7     impression(F'la personne    est âge[person]    ans.')
    8 sauf KeyError:
    9     impression(F"la personnel'âge de est inconnu. ")

Ici, vous pouvez voir le cas normal dans le essayer bloc d’impression du nom et de l’âge de la personne. Le cas de sauvegarde est dans le sauf bloc, où si un KeyError est levé dans le cas normal, le cas de sauvegarde consiste à imprimer un message différent.

le essayer sauf la solution de blocage est également une excellente solution pour d'autres endroits qui pourraient ne pas supporter .obtenir() ou la dans opérateur. C’est aussi la meilleure solution si le KeyError est élevé à partir du code d'une autre personne.

Voici un exemple utilisant le fichier zip paquet encore. Cette fois, le essayer sauf bloquer nous donne un moyen d'arrêter la KeyError exception à l'arrêt du programme:

>>>

>>> de fichier zip importation Fichier zip
>>> Zip *: français = Fichier zip('the_zip_file.zip')
>>> essayer:
...     Zip *: français.getinfo('quelque chose')
... sauf KeyError:
...     impression('Vous ne trouvez pas "quelque chose"')
...
Vous ne trouvez pas "quelque chose"

Depuis le Fichier zip la classe ne fournit pas .obtenir(), comme le dictionnaire, vous devez utiliser le essayer sauf Solution. Dans cet exemple, il n’est pas nécessaire de connaître à l’avance les valeurs valides à transmettre à .getinfo ().

Conclusion

Vous connaissez maintenant des endroits communs où Python KeyError Une exception pourrait être soulevée et quelques bonnes solutions que vous pourriez utiliser pour les empêcher d’arrêter votre programme.

Maintenant, la prochaine fois que vous voyez un KeyError élevé, vous saurez que c’est probablement une mauvaise recherche de clé de dictionnaire. Vous pourrez également trouver toutes les informations dont vous avez besoin pour déterminer la source de l'erreur en consultant les dernières lignes de la trace.

Si le problème est une recherche de clé de dictionnaire dans votre propre code, vous pouvez alors passer de l’accès direct à la clé du dictionnaire à l’utilisation du plus sûr. .obtenir() méthode avec une valeur de retour par défaut. Si le problème ne provient pas de votre propre code, utilisez le essayer sauf bloquer est le meilleur moyen de contrôler le flux de votre code.

Les exceptions ne doivent pas être effrayantes. Une fois que vous savez comprendre les informations qui vous sont fournies dans leurs retraits et la cause première de l'exception, vous pouvez utiliser ces solutions pour que vos programmes se déroulent de manière plus prévisible.