Ga naar hoofdinhoud

Python KeyError-excepties en hoe je ze oplost

Leer belangrijke technieken zoals exceptieafhandeling en foutpreventie om de KeyError-exceptie in Python effectief te behandelen.
· 6 min lezen

Verken met AI

Zelfs de meest ervaren programmeurs maken wel eens codeerfouten. Voor Python-programmeurs vallen deze fouten in twee categorieën: errors of excepties.

Errors hebben vooral met syntax te maken. Je moet ze oplossen voordat het programma kan draaien. Een exceptie daarentegen treedt op wanneer de code syntactisch correct is, maar er tijdens het uitvoeren iets gebeurt dat het programma onderbreekt. 

In deze tutorial bekijken we een van de meest voorkomende excepties waar zowel beginnende als ervaren programmeurs mee te maken krijgen: de KeyError-exceptie. We behandelen de details van Python’s KeyError, met voorbeelden en verschillende technieken om dit type exceptie af te handelen. Wil je leren hoe je fouten in Python herkent en oplost, bekijk dan ook onze tutorial Exception & Error Handling in Python. 

Wat is een KeyError-exceptie?

In Python is een KeyError-exceptie een van de ingebouwde excepties die bedoeld is om een breed scala aan veelvoorkomende foutcondities af te handelen. Een KeyError kun je begrijpen als een subklasse, samen met IndexError, van de meer algemene LookupError-exceptie; al deze zijn objecten van de klasse Exception.

Specifiek wordt een KeyError-exceptie opgegooid wanneer een programmeur probeert een sleutel te benaderen die niet bestaat in een dictionary. Een dictionary is, ter referentie, een datastructuur die gegevens opslaat in key-valueparen; de waarde in een dictionary wordt benaderd via de sleutel — vandaar de naam KeyError. 

Veelvoorkomende oorzaken van Python KeyError en voorbeelden

Laten we een voorbeeld bekijken met een dictionary van landen en hun hoofdsteden:

dictionary_capitals = {'Madrid': 'Spain',
 'Lisboa': 'Portugal', 'London': 'United Kingdom'}

Om in onze dictionary te zoeken, moeten we de sleutel tussen blokhaken opgeven en Python geeft de bijbehorende waarde terug.

dictionary_capitals['Madrid']
'Spain'

Als we proberen een sleutel te benaderen die niet in de dictionary staat, geeft Python ons de foutmelding van de KeyError-exceptie. 

dictionary_capitals['Rome']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'Rome'

We kunnen ook een KeyError-exceptie tegenkomen wanneer we niet-bestaande sleutels proberen te benaderen in andere Python-mappingobjecten die de vorm van een dictionary aannemen. Zo retourneert het object os.environ een dictionary die de omgevingsvariabelen van de gebruiker als sleutels opslaat met hun bijbehorende waarden.

In de volgende code proberen we de waarde te benaderen die is gekoppeld aan de sleutel USERS in de os.environ-dictionary. Omdat USERS niet in de os.environ-dictionary stond, levert onze code een KeyError op.

#Calling a non-existent environmental variable
os.environ['USERS']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/os.py", line 679, in __getitem__
    raise KeyError(key) from None
KeyError: 'USERS'

Zoals blijkt, zijn dictionaries heel gebruikelijk in Python. Een ander voorbeeld is de implementatie van iets abstracter, een hashmap. Bekijk onze tutorial Guide to Python Hashmaps om meer te leren over hashmaps.

Python KeyError-excepties afhandelen

Laten we methoden verkennen om KeyError-excepties af te handelen. We hebben twee strategieën: we kunnen KeyError voorkomen, of KeyError opvangen met exceptieafhandeling. 

KeyError voorkomen

Zoals we hebben gezien, gooit Python een KeyError als we een niet-bestaande sleutel proberen te benaderen. Om dit te voorkomen kunnen we sleutels in een dictionary benaderen met de methode .get(), zodat onze code vergevingsgezinder is. Als we met deze methode een niet-bestaande sleutel tegenkomen, retourneert Python de waarde None in plaats van een KeyError. Dit is een goede aanpak.

print(dictionary_capitals.get('Prague'))
None

Een andere mogelijkheid is eerst te controleren of een sleutel bestaat voordat we deze benaderen. Deze manier om excepties te voorkomen staat bekend als “Look Before You Leap”, of kortweg LBYL. In dit geval kunnen we if-statements gebruiken om te checken of de sleutel bestaat en zo niet, het probleem afhandelen in de else-clausule.

capital = "Prague"
if capital in dictionary_capitals.keys():
    value = dictionary_capitals[capital]
else:
    print("The key {} is not present in the dictionary".format(capital)) 

KeyError opvangen met exceptieafhandeling

Een tweede aanpak staat bekend als “Easier to Ask Forgiveness Than Permission”. EAFP, zoals het heet, is eigenlijk de meer gangbare manier om excepties in Python af te handelen. 

Als je de EAFP-codestijl hanteert, ga je uit van het bestaan van geldige sleutels en vang je excepties op als die aanname onjuist blijkt. Waar onze LBYL-aanpak leunt op if/else-statements, vertrouwt de EAFP-aanpak op try/except-clausules. 

In het volgende voorbeeld proberen we, in plaats van te controleren of de sleutel aanwezig is, de gewenste sleutel direct te benaderen. Als de sleutel om wat voor reden dan ook niet aanwezig is, vangen we de KeyError op in de except-clausule en handelen we die passend af.

capital = "Prague"
try:
     value = dictionary_capitals[capital]
except KeyError:
     print("The key {} is not present in the dictionary".format(capital)) 

Geavanceerd beheer van Python KeyError

defaultdict gebruiken voor automatische sleutelafhandeling

We zien dat Python een KeyError-exceptie retourneert telkens wanneer we een sleutel proberen te benaderen die niet in onze dictionary staat. De methode .get() die we bespraken was een fouttolerante aanpak die prima werkte, maar niet geoptimaliseerd was.

De module Collections biedt defaultdict, een meer geoptimaliseerde aanpak voor het afhandelen van dictionary-items. In tegenstelling tot standaarddictionaries die een KeyError gooien als we een niet-bestaande sleutel benaderen, laat een defaultdict ons een standaardwaarde opgeven die wordt geretourneerd wanneer een sleutel niet wordt gevonden. De volgende code laat zien hoe we defaultdict uit Collections importeren en een standaardwaarde maken met een lambda-functie. Ben je in de war over lambda-functies, bekijk dan onze Python lambda Tutorial om meer te leren.

from collections import defaultdict 

# Defining the dict 
capitals = defaultdict(lambda: "The key doesn't exist") 
capitals['Madrid'] = 'Spain'
capitals['Lisboa'] = 'Portugal'
print(capitals['Madrid']) 
print(capitals['Lisboa']) 
print(capitals['Ankara'])
Spain
Portugal
The key doesn't exist

Opzettelijk KeyErrors opwerpen

Tot slot moeten we zeggen dat het in sommige situaties passend kan zijn om bewust een KeyError op te werpen om bepaalde randvoorwaarden af te dwingen.

We weten dat functies in veel gevallen afhankelijk zijn van specifieke gegevens die beschikbaar moeten zijn om hun taken uit te voeren. Een KeyError handmatig triggeren zorgt er dus voor dat de functie duidelijk en voorspelbaar faalt wanneer vereiste data ontbreken. In zulke gevallen helpt de foutmelding die bij de KeyError wordt meegegeven ons precies te begrijpen wat er mis was met de aangeleverde input, wat het debuggen makkelijker maakt.

Laten we dit verduidelijken met een voorbeeld. Hier hebben we een functie gemaakt die een dictionary als argument neemt. De gebruiker moet de dictionary met de juiste sleutels aanleveren zodat de functie correct werkt. We maken in dit geval een functie omdat we meteen willen weten of sleutels ontbreken, in plaats van fouten verderop in de code te laten doorsudderen. 

def my_function(my_dict): 
    if 'critical_key' not in my_dict: 
        raise KeyError('critical_key is missing from the dictionary. Please modify the dictionary')

Conclusie

Hopelijk vond je dit artikel nuttig. KeyError is een van de meest voorkomende excepties waar een Python-ontwikkelaar mee te maken krijgt. Het beheersen van fout- en exceptieafhandeling is een essentieel onderdeel van sterker worden als Python-programmeur. Leer meer over andere functionele programmeertechnieken en andere codeerfundamenten met onze skill tracks Python Programming en Python Fundamentals. Bekijk ook onze tutorial Python Sets and Set Theory om meer te leren over aanverwante concepten. 

Javier Canales Luna

Auteur

Javier Canales Luna

Ik ben een freelance data-analist en werk samen met bedrijven en organisaties wereldwijd aan data­scienceprojecten. Ook geef ik les in data science en heb ik meer dan twee jaar ervaring als docent. Ik schrijf regelmatig artikelen over data science in het Engels en Spaans; sommige daarvan zijn gepubliceerd op bekende platforms zoals DataCamp, Towards Data Science en Analytics Vidhya. Als data scientist met een achtergrond in politicologie en recht wil ik werken op het snijvlak van openbaar beleid, recht en technologie. Ik zet de kracht van ideeën in om innovatieve oplossingen en verhalen te ontwikkelen die helpen bij het aanpakken van urgente uitdagingen, met name de klimaatcrisis. Ik beschouw mezelf als autodidact, een eeuwige leerling en een groot voorstander van multidisciplinariteit. Het is nooit te laat om nieuwe dingen te leren.

Onderwerpen

Gerelateerd