Ana içeriğe geç

Python KeyError İstisnaları ve Nasıl Düzeltilir

Python'da KeyError istisnasını etkili şekilde ele almak için istisna yakalama ve hata önleme gibi temel teknikleri öğrenin.
· 6 dk. oku

Yapay Zeka ile Keşfedin

En deneyimli programcılar bile kodlama hataları yapar. Python programcıları için bu hatalar iki kategoriye ayrılır: hatalar ve istisnalar.

Hatalar öncelikle sözdizimiyle ilgilidir. Programın çalışması için düzeltilmeleri gerekir. Öte yandan istisna, kod sözdizimi açısından doğru olsa da, program çalışırken bir şeyin yürütmeyi kesintiye uğratmasıyla meydana gelir. 

Bu eğitimde, hem yeni hem de deneyimli programcıların sıkça karşılaştığı istisnalardan birine, KeyError istisnasına bakacağız. Python’un KeyError ayrıntılarını, örneklerle ve bu tür istisnaları ele almak için farklı tekniklerle ele alacağız. Python'da hataları nasıl tespit edip düzelteceğinizi öğrenmek istiyorsanız, Python'da İstisna ve Hata Yönetimi eğitimimize de göz atın. 

KeyError İstisnası Nedir?

Python'da KeyError istisnası, yaygın hata durumlarının geniş bir yelpazesini ele almak için tasarlanmış yerleşik istisnalardan biridir. KeyError, IndexError ile birlikte daha genel LookupError istisnasının bir alt sınıfı olarak anlaşılabilir ve bunların tümü Exception sınıfının nesneleridir.

Özellikle, bir programcı sözlükte bulunmayan bir anahtara erişmeye çalıştığında KeyError istisnası yükseltilir. Referans olarak, sözlük (dictionary) anahtar-değer çiftleri halinde veri saklayan bir veri yapısıdır ve sözlükteki değere anahtarı aracılığıyla erişilir — bu yüzden adı KeyError olmuştur. 

Python KeyError Yaygın Nedenler ve Örnekler

Ülkeler ve başkentlerinden oluşan bir sözlük örneğine bakalım:

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

Sözlüğümüzde bilgi aramak için, köşeli parantez içinde anahtarı belirtmemiz yeterlidir; Python ilişkili değeri döndürecektir.

dictionary_capitals['Madrid']
'Spain'

Sözlükte olmayan bir anahtara erişmeye çalışırsak Python bize bir KeyError istisna hata mesajı verir. 

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

Sözlük biçimini benimseyen diğer Python eşleme (mapping) nesnelerinde de var olmayan anahtarlara erişmeye çalıştığımızda KeyError istisnasıyla karşılaşabiliriz. Örneğin os.environ nesnesi, kullanıcının ortam değişkenlerini anahtarlar ve bunlara ilişkin değerler olarak saklayan bir sözlük döndürür.

Aşağıdaki kodda, os.environ sözlüğünde USERS anahtarıyla ilişkili değere erişmeye çalışıyoruz. USERS os.environ sözlüğünde bulunmadığından kodumuz bir KeyError verir.

#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'

Görüldüğü gibi, sözlükler Python'da oldukça yaygındır. Bir diğer örnek de daha soyut bir kavram olan hashmap uygulamasıdır. Hashmap'ler hakkında daha fazla bilgi edinmek için Python Hashmap'lerine Rehber adlı eğitimimize göz atın.

Python KeyError İstisnalarını Yönetme

KeyError istisnalarını ele alma yöntemlerini inceleyelim. İki stratejimiz var: Ya KeyError'ı önleyebilir ya da hata yakalama ile KeyError'ı yakalayabiliriz. 

KeyError'ı önleme

Gördüğümüz gibi, var olmayan bir anahtara erişmeye çalışırsak Python bir KeyError fırlatır. Bunu önlemek için, sözlükteki anahtarlara daha esnek davranmak adına .get() yöntemini kullanarak erişebiliriz. Bu yöntemi kullanırken var olmayan bir anahtarla karşılaşırsak, Python KeyError yerine None değeri döndürür. Bu iyi bir yaklaşımdır.

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

Alternatif olarak, erişmeden önce bir anahtarın var olup olmadığını kontrol edebiliriz. İstisnaları bu şekilde önlemeye “Atlamadan Önce Bak" (Look Before You Leap - LBYL) denir. Bu durumda, anahtarın var olup olmadığını kontrol etmek için if deyimlerini kullanabilir, yoksa sorunu else bloğunda ele alabiliriz.

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

İstisna yakalama ile KeyError'ı yakalama

İkinci bir yaklaşım da “İzin İstemektense Af Dilemek Daha Kolaydır" (Easier to Ask Forgiveness Than Permission) olarak bilinir. Kısaca EAFP denilen bu yaklaşım, Python'da istisnaları ele almanın daha standart yoludur. 

EAFP kodlama stilini benimsemek, geçerli anahtarların var olduğunu varsaymak ve bu varsayım yanlış çıkarsa istisnaları yakalamak anlamına gelir. LBYL yaklaşımımız if/else deyimlerine dayanırken, EAFP yaklaşımı try/except bloklarına dayanır. 

Aşağıdaki örnekte, anahtarın mevcut olup olmadığını kontrol etmek yerine istenen anahtara erişmeyi deneriz. Herhangi bir nedenle anahtar mevcut değilse, except bloğunda KeyError'ı yakalar ve uygun şekilde ele alırız.

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

İleri Düzey Python KeyError Yönetimi

Otomatik anahtar işleme için defaultdict kullanma

Sözlüğümüzde olmayan bir anahtara her erişmeye çalıştığımızda Python'un bir KeyError istisnası döndürdüğünü görüyoruz. İncelediğimiz .get() yöntemi hataya toleranslı bir yaklaşımdı ve işe yaradı, ancak optimize edilmemişti.

Collections modülü, sözlük girdilerini ele almak için daha optimize bir yaklaşım olan defaultdict sunar. Var olmayan bir anahtara erişmeye çalıştığımızda KeyError fırlatan standart sözlüklerin aksine, defaultdict bir anahtar bulunamadığında döndürülecek varsayılan bir değer belirtmemize olanak tanır. Aşağıdaki kod, Collections içinden defaultdict'in nasıl içe aktarılacağını ve bir lambda işleviyle varsayılan değerin nasıl oluşturulacağını gösterir. Lambda işlevleri kafanızı karıştırıyorsa, daha fazla bilgi için Python lambda Eğitimimize göz atın.

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

KeyError'ları kasıtlı olarak yükseltmek

Son olarak, bazı durumlarda belirli kısıtları sağlamak için bir KeyError'ı kasıtlı olarak yükseltmenin uygun olabileceğini söylemeliyiz.

Biliyoruz ki pek çok durumda, fonksiyonlar işlemlerini gerçekleştirmek için belirli verilerin mevcut olmasına dayanır. Bir KeyError'ın elle tetiklenmesi, gerekli veriler eksik olduğunda fonksiyonun net ve öngörülebilir şekilde başarısız olmasını sağlar. Bu durumlarda, KeyError ile verilen hata mesajı, sağlanan girdide tam olarak neyin yanlış olduğunu anlamamıza yardımcı olur ve hata ayıklamayı kolaylaştırır.

Bir örnekle netleştirelim. Burada argüman olarak bir sözlük alan bir fonksiyon oluşturduk. Fonksiyonun doğru çalışması için kullanıcının sözlüğü doğru anahtarlarla sağlaması gerekir. Bu durumda bir fonksiyon oluşturuyoruz çünkü hataların kodun ilerleyen kısımlarına sarkmasına izin vermek yerine, anahtarlar eksikse bunu hemen bilmek istiyoruz. 

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')

Sonuç

Umarız bu makaleden keyif almışsınızdır. KeyError, bir Python geliştiricisinin karşılaşacağı en yaygın istisnalardan biridir. Hata ve istisna yönetiminde ustalaşmak, güçlü bir Python programcısı olmanın kilit parçasıdır. Diğer fonksiyonel programlama tekniklerini ve temel kodlama konularını Python Programming ve Python Fundamentals beceri yollarımızla öğrenin. Ayrıca, ilişkili kavramlar hakkında daha fazla bilgi için Python Kümeleri ve Kümeler Teorisi eğitimimize de göz atın. 

Javier Canales Luna

Yazar

Javier Canales Luna

Serbest çalışan bir veri analistiyim; dünya genelinde şirketler ve kuruluşlarla veri bilimi projelerinde iş birliği yapıyorum. Ayrıca 2+ yıllık deneyime sahip bir veri bilimi eğitmeniyim. Düzenli olarak İngilizce ve İspanyolca veri bilimiyle ilgili makaleler yazıyorum; bunların bir kısmı DataCamp, Towards Data Science ve Analytics Vidhya gibi köklü internet sitelerinde yayımlandı. Siyaset bilimi ve hukuk geçmişine sahip bir veri bilimci olarak amacım, kamu politikası, hukuk ve teknolojinin kesişiminde çalışmak; fikirlerin gücünden yararlanarak özellikle iklim krizi olmak üzere acil sorunların üstesinden gelmemize yardımcı olabilecek yenilikçi çözümler ve anlatılar geliştirmek. Kendimi otodidakt bir kişi, sürekli öğrenen ve disiplinlerarasılığın güçlü bir savunucusu olarak görüyorum. Yeni şeyler öğrenmek için asla geç değildir.

Konular

İlgili