Python “‘NoneType’ object is not subscriptable” hatası, köşeli parantezle indeks veya anahtar üzerinden erişilmeye çalışılan değişkenin değeri None olduğunda çıkar. Python, None değerini bir liste, sözlük ya da benzeri bir veri yapısı gibi alt öğelerine ayıramadığı için veri[0] veya veri['puan'] ifadelerini çalıştıramaz.
Bu hatayı anlamanın en kısa yolu, köşeli parantezden önceki değişkeni kontrol etmektir. Hata mesajındaki subscriptable ifadesi, bir değere indeks ya da anahtar kullanarak erişilebilmesini anlatır. Aşağıdaki örnekte veri değişkeni None olduğu için ilk elemana erişim başarısız olur:
Hata mesajı, None değere indeksleme yapıldığını anlatır

İndeksleme, bir veri yapısının belirli konumundaki elemana veya sözlükteki belirli anahtara köşeli parantezle ulaşmaktır. Listelerde liste[0], sözlüklerde ise sozluk['puan'] biçimleri kullanılır. Bu ifadelerde köşeli parantezden önceki değer None ise Python, hangi alt öğenin alınacağını bulamaz.
veri = None
print(veri[0])
Bu kod çalıştırıldığında hata çıktısının son satırı şöyledir:
TypeError: 'NoneType' object is not subscriptable
Buradaki TypeError, yapılan işlemin veri türüyle uyumlu olmadığını gösterir. Python, None değerini liste veya sözlük gibi indekslenebilir bir tür olarak değerlendiremez. Benzer bir durum anahtar kullanırken de ortaya çıkar:
sonuc = None
print(sonuc['puan'])
İki örnekte de sorun, kullanılan indeksin veya anahtarın yanlış yazılması değildir. Sorun, bu erişimin yapılacağı değişkenin beklenen veri yapısı yerine None taşımasıdır. None değerinin nereden geldiğini bulmak için hatalı satırın öncesindeki atamaları ve fonksiyon çağrılarını incelemek gerekir.
Traceback, hatalı satırı bulmayı nasıl sağlar?
Traceback, Python hata oluştuğunda programın hangi çağrı yolundan ilerlediğini gösteren hata raporudur. Raporun en alt kısmında genellikle dosya adı, satır numarası ve çalıştırılan kod ifadesi yer alır; en son satırda da hata türüyle açıklaması bulunur.
veri = None
print(veri[0])
Bu kod bir dosyada çalıştırıldığında traceback bölümünün önemli kısmı şu yapıda görünür:
Traceback (most recent call last):
File "ornek.py", line 2, in <module>
print(veri[0])
TypeError: 'NoneType' object is not subscriptable
İlk olarak en alttaki kod ifadesine bakılır. Burada hata, veri[0] erişiminde oluşmuştur. Ardından veri değişkeninin hangi satırda oluşturulduğu, bir fonksiyondan dönüp dönmediği veya başka bir işlemin sonucunda atanıp atanmadığı geriye doğru takip edilir.
Hata veren satır ile None değerini üreten satır farklı olabilir. Aşağıdaki örnekte fonksiyon None döndürür, hata ise fonksiyon çağrısından sonra ortaya çıkar:
def veriyi_getir():
return None
sonuc = veriyi_getir()
print(sonuc)
print(type(sonuc))
try:
print(sonuc[0])
except TypeError as hata:
print(hata)
Bu kodun çıktısı şöyledir:
None
<class 'NoneType'>
'NoneType' object is not subscriptable
print(sonuc) değerin gerçekten None olup olmadığını, print(type(sonuc)) ise değişkenin veri türünü gösterir. Bu iki kontrol, traceback'teki hatalı erişim satırından geriye giderek sorunun hangi işlemden kaynaklandığını belirlemeye yardımcı olur.
Bu hata en sık hangi kod desenlerinden çıkar?

Bu hata genellikle indeksleme yaptığın değişkenin beklediğin liste, sözlük ya da eşleşme nesnesi yerine None taşımasıyla oluşur. En sık karşılaşılan kaynaklar, dönüş değeri unutulan fonksiyonlar, yerinde sıralama yapan list.sort() çağrıları ve sonuç bulunamadığında None dönebilen yöntemlerdir.
Açık bir return yazılmamış fonksiyon
Fonksiyon içinde return yazılmazsa fonksiyonun sonucu None olur. Bu nedenle fonksiyon çağrısının hemen ardından indeksleme yapmak hataya yol açabilir. return, fonksiyonun dışarıya bir değer göndermesini sağlar. Python belgelerinde, fonksiyonun sonuna dönüş değeri verilmeden ulaşılması durumunda None döndüğü belirtilir.
def ilk_not(notlar):
sirali = sorted(notlar, reverse=True)
# return unutuldu
sonuc = ilk_not([72, 95, 88])
print(sonuc[:3])
Bu kodda sonuc değişkeni None olur. None[:3] ifadesi çalıştırıldığında TypeError: 'NoneType' object is not subscriptable hatası alınır.
list.sort() sonucunu değişkene atamak
Metot, bir nesne üzerinde çağrılan işlemdir. Örneğin notlar.sort() ifadesinde sort(), notlar listesi üzerinde çalışır. Yerinde değiştirme ise mevcut nesnenin doğrudan değiştirilmesi ve yeni sonucu ayrı bir değer olarak vermeme durumudur. list.sort() listeyi yerinde sıralar ve sonuç olarak kullanılacak yeni bir liste döndürmez. Bu nedenle çağrının sonucu None olur.
notlar = [72, 95, 88, 61, 100, 84]
notlar = notlar.sort(reverse=True)
print(notlar[:3])
Burada liste sıralama işlemi sırasında değişir, ancak atama sonrasında notlar değişkeni None değerini alır. Yeni bir sıralı listeye ihtiyacın varsa sorted() kullanabilirsin.
notlar = [72, 95, 88, 61, 100, 84]
ilk_uc = sorted(notlar, reverse=True)[:3]
print(ilk_uc)
Bu sürümün çıktısı [100, 95, 88] olur. sorted(), verilen verilerden yeni bir sıralı liste oluşturur.
Mevcut listeyi doğrudan sıralamak istiyorsan sort() çağrısını atama yapmadan kullanmalısın.
notlar = [72, 95, 88, 61, 100, 84]
notlar.sort(reverse=True)
print(notlar[:3])
Bu sürüm de [100, 95, 88] çıktısını verir. İlk sürümde yeni bir liste oluşturulur, ikinci sürümde aynı liste değiştirilir.
re.match() ve dict.get() sonucunu doğrudan indekslemek
re.match(), metnin başlangıcında eşleşme bulamazsa None döndürebilir. Eşleşme sonucunu kontrol etmeden [0] ile okumaya çalışmak bu hatayı üretir.
Benzer durum dict.get() için de geçerlidir. Aranan anahtar bulunamazsa varsayılan değer verilmediği sürece sonuç None olur. Ardından bu değere indeksleme yapılırsa aynı TypeError ortaya çıkar.
Hata nasıl düzeltilir ve ne zaman kontrol eklenir?
Düzeltme için önce None değerinin nereden geldiğini bulmalısın. Fonksiyonda doğru noktaya return eklemek, yeni sıralı liste gerektiğinde sorted() kullanmak, yerinde sıralamada sort() çağrısını atamadan çalıştırmak ve belirsiz sonuçları kullanmadan önce kontrol etmek temel adımlardır.
def ilk_uc(notlar):
sirali = sorted(notlar, reverse=True)
return sirali[:3]
sonuc = ilk_uc([72, 95, 88, 61])
print(sonuc)
Bu kodun çıktısı [95, 88, 72] olur. return satırı, fonksiyonun hazırladığı listeyi sonuc değişkenine aktarır.
Eşleşme veya sözlük anahtarı bulunamayabilecek durumlarda, sonucu kullanmadan önce is not None kontrolü ekleyebilirsin.
import re
eslesme = re.match(r"Python", "Java dersi")
kod = {"dil": "Python"}.get("kod")
if eslesme is not None:
print(eslesme[0])
else:
print("Eşleşme bulunamadı")
if kod is not None:
print(kod[0])
else:
print("Anahtar bulunamadı")
Bu örnekte çıktı sırasıyla Eşleşme bulunamadı ve Anahtar bulunamadı olur. Böylece None üzerinde indeksleme yapılmadan güvenli akış korunur.
Hata ayıklarken şu sırayı izleyebilirsin:
- İndeksleme yapılan değişkeni
print()ile yazdır. type(degisken)ile değişkenin türünü kontrol et.Nonedeğerinin üretildiği fonksiyon veya satırı bul.- Gerekiyorsa doğru dönüş değerini ekle.
- Sonuç bulunamayabilecekse
if sonuc is not Nonekontrolü kullan.
try/except ile hatayı yakalamak programın durmasını engelleyebilir, ancak None değerinin neden oluştuğunu açıklamaz. Asıl kaynağı düzeltmeden hatayı sessizce geçmek, aynı sorunun başka bir satırda yeniden ortaya çıkmasına neden olabilir.
Sık Sorulan Sorular
“NoneType” object is not subscriptable hatası ile AttributeError arasındaki fark nedir?
NoneType object is not subscriptable hatası, None değerine [] ile indeksleme veya dilimleme yapılmaya çalışıldığını gösterir. AttributeError ise bir nesnede bulunmayan özellik ya da metot kullanılmaya çalışıldığında ortaya çıkar.
list.sort() neden sonucu bir değişkene atandığında bu hataya yol açar?
list.sort() mevcut listeyi yerinde sıralar ve kullanılabilir yeni bir liste döndürmez. Bu nedenle notlar = notlar.sort() yazıldığında notlar değişkeni None olur ve sonrasında yapılan indeksleme bu hatayı üretir.
try/except kullanmak bu hatayı gerçekten düzeltir mi?
try/except hatayı yakalayabilir, ancak None değerini üreten fonksiyon veya işlem düzeltilmedikçe temel sorunu çözmez. Önce kaynağı bulmak, ardından doğru return ya da koşul kontrolünü eklemek gerekir.
Bir fonksiyonun None döndürdüğünü indeksleme yapmadan nasıl kontrol edebilirim?
Fonksiyon sonucunu önce bir değişkende tutup if sonuc is not None: koşuluyla kontrol edebilirsin. Bu koşul sağlanıyorsa indeksleme yapılır, sağlanmıyorsa alternatif akış çalıştırılır.
Bu hata, indeksleme yapılan değerin gerçekten beklediğin nesne olup olmadığını kontrol ederek ve değeri üreten kodu inceleyerek adım adım çözülebilir.