Python bir hata mesajı verdiğinde en önemli bilgi son satırdadır: önce istisnanın sınıfı (NameError, TypeError gibi), iki noktadan sonra ne olduğunu anlatan mesaj gelir. Hemen üstündeki satırlar hatanın hangi dosyada, hangi satırda ve hangi ifadede oluştuğunu gösterir. Yeni Python sürümleri bu mesajlara giderek daha fazla öneri ekliyor; "Did you mean ...?" ile biten bir satır çoğu zaman çözümün kendisidir.

Bu yazıda yeni başlayanların ve deneyimli geliştiricilerin en sık karşılaştığı hata mesajlarını tek tek çalıştırıp gerçek çıktılarını gösteriyoruz: söz dizimi ve girinti hataları, NameError, UnboundLocalError, TypeError, AttributeError, KeyError, IndexError, içe aktarma hataları ve diğerleri. Tüm mesajlar Python 3.15.2 ile alındı; dosya yolunu ornek.py olarak kısalttık, başka bir şeyi değiştirmedik. Eski sürümlerde aynı hata farklı ya da daha az yardımcı bir mesajla görünebilir.

Bir traceback nasıl okunur?

Bir traceback nasıl okunur?

Programın çalışması sırasında yakalanmayan bir istisna oluştuğunda Python bir traceback (geri izleme) yazdırır. İlk satır her zaman "Traceback (most recent call last):" olur; yani en son yapılan çağrı en altta yer alır. Her çağrı için bir File "...", line N, in ... satırı ve altında o satırın kaynak kodu görünür. 3.11 ile gelen PEP 657 sayesinde traceback, hatanın ifadenin tam olarak hangi parçasında oluştuğunu ^ ve ~ işaretleriyle vurgular. 3.13 ile traceback terminalde varsayılan olarak renkli yazılır; bu, PYTHON_COLORS, NO_COLOR ve FORCE_COLOR ortam değişkenleriyle denetlenebilir.

python
sayac = 0

def artir():
    sayac += 1

artir()
# Traceback (most recent call last):
#   File "ornek.py", line 6, in <module>
#     artir()
#     ~~~~~^^
#   File "ornek.py", line 4, in artir
#     sayac += 1
#     ^^^^^
# UnboundLocalError: cannot access local variable 'sayac' where it is not associated with a value

Bu traceback'i aşağıdan yukarı okuyalım: hata UnboundLocalError, 4. satırdaki artir fonksiyonunun içinde, sayac adında oluştu; o fonksiyon da 6. satırda modül düzeyinden çağrılmıştı. İç içe çağrılarda sorun genellikle kendi yazdığınız en alttaki satırdadır; standart kütüphane dosyalarına ait satırlar çoğunlukla yanlış argümanın nereden geldiğini gösterir.

Söz dizimi hataları farklı görünür: program hiç çalışmadan, ayrıştırma aşamasında yakalandıkları için "Traceback" satırı ve çağrı zinciri yoktur, yalnızca dosya, satır ve işaret gösterilir.

SyntaxError: söz dizimi hataları

SyntaxError, ayrıştırıcının kodu Python kurallarına uygun bulmadığı anlamına gelir. Yorumlayıcı hatayı fark ettiği yeri işaretler; ancak asıl eksik bazen bir önceki satırdadır. En sık görülen biçimler şunlardır. Bloğu açan satırda iki nokta eksikse:

python
sayi = 5
if sayi > 3
    print('büyük')
#   File "ornek.py", line 2
#     if sayi > 3
#                ^
# SyntaxError: expected ':'

Anahtar kelime yanlış yazıldığında Python 3.14 ile gelen öneri devreye girer:

python
whille True:
    break
#   File "ornek.py", line 1
#     whille True:
#     ^^^^^^
# SyntaxError: invalid syntax. Did you mean 'while'?

Kapatılmamış tırnak ve parantez hataları, sorunun başladığı yeri gösterir. Parantez örneğinde hata 1. satırda bildiriliyor, çünkü açılan köşeli parantez hiç kapanmadı:

python
print('merhaba)
#   File "ornek.py", line 1
#     print('merhaba)
#           ^
# SyntaxError: unterminated string literal (detected at line 1)
python
liste = [1, 2, 3
print(liste)
#   File "ornek.py", line 1
#     liste = [1, 2, 3
#             ^
# SyntaxError: '[' was never closed

Karşılaştırma yerine atama yazmak ve argümanlar arasındaki virgülü unutmak için de özel ipuçları var:

python
x = 5
if x = 5:
    pass
#   File "ornek.py", line 2
#     if x = 5:
#        ^^^^^
# SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='?
python
print('Sonuç' 42)
#   File "ornek.py", line 1
#     print('Sonuç' 42)
#           ^^^^^^^^^^
# SyntaxError: invalid syntax. Perhaps you forgot a comma?

3.14 ile else bloğundan sonra gelen elif için de ayrı bir mesaj eklendi. Koşul yapısının doğru sırası için if elif else yazısına bakabilirsiniz:

python
def f(x):
    if x > 0:
        return 'pozitif'
    else:
        return 'değil'
    elif x == 0:
        return 'sıfır'
#   File "ornek.py", line 6
#     elif x == 0:
#     ^^^^
# SyntaxError: 'elif' block follows an 'else' block

IndentationError ve TabError

Python blokları girintiyle belirlediği için girinti hataları SyntaxError sınıfının alt sınıfı olan IndentationError ile bildirilir. İki noktayla biten bir satırdan sonra girintili blok gelmezse mesaj, bloğu açan satırı da söyler:

python
if True:
print('girinti yok')
#   File "ornek.py", line 2
#     print('girinti yok')
#     ^^^^^
# IndentationError: expected an indented block after 'if' statement on line 1

Tersine, beklenmeyen yerde fazladan girinti varsa:

python
def f():
    x = 1
        y = 2
#   File "ornek.py", line 3
#     y = 2
# IndentationError: unexpected indent

Aynı blokta sekme (tab) ve boşluk karıştırıldığında IndentationError sınıfının alt sınıfı olan TabError oluşur. Aşağıdaki kodun üçüncü satırı boşluk yerine bir sekme karakteriyle girintilenmiştir:

python
def f():
    x = 1
	y = 2
# TabError: inconsistent use of tabs and spaces in indentation

NameError ve UnboundLocalError

NameError ve UnboundLocalError

NameError, tanımlanmamış bir adın kullanıldığını söyler. Yazım hatası yapılmışsa yorumlayıcı yakın bir ad önerir; standart kütüphane modülünü içe aktarmayı unuttuysanız bunu da hatırlatır:

python
toplam_tutar = 150
print(toplam_tuttar)
# Traceback (most recent call last):
#   File "ornek.py", line 2, in <module>
#     print(toplam_tuttar)
#           ^^^^^^^^^^^^^
# NameError: name 'toplam_tuttar' is not defined. Did you mean: 'toplam_tutar'?
python
print(math.pi)
# Traceback (most recent call last):
#   File "ornek.py", line 1, in <module>
#     print(math.pi)
#           ^^^^
# NameError: name 'math' is not defined. Did you forget to import 'math'?

UnboundLocalError, NameError sınıfının alt sınıfıdır ve yazının başındaki örnekte gördüğümüz gibi bir fonksiyon içinde, değer atanmadan önce okunan yerel değişken için fırlatılır. Fonksiyonun herhangi bir yerinde bir ada atama yapılırsa o ad bütün fonksiyon boyunca yerel kabul edilir; sayac += 1 hem okuma hem atama olduğu için modül düzeyindeki sayac görülmez. Çözüm, gerçekten global değişkeni değiştirmek istiyorsanız global sayac yazmak ya da daha iyisi değeri parametre olarak alıp sonuç döndürmektir. Kurallar kapsam, global ve nonlocal yazısında.

TypeError: yanlış tip ya da yanlış çağrı

TypeError, bir işlemin uygun olmayan tipte bir nesneye uygulandığını gösterir. Belki de en sık görüleni metinle sayıyı + ile birleştirmektir:

python
yas = 30
print('Yaş: ' + yas)
# Traceback (most recent call last):
#   File "ornek.py", line 2, in <module>
#     print('Yaş: ' + yas)
#           ~~~~~~~~^~~~~
# TypeError: can only concatenate str (not "int") to str

Çözüm str(yas) ile dönüştürmek ya da f-string kullanmaktır: f'Yaş: {yas}'. Fonksiyon çağrılarında eksik ya da yanlış adlı argümanlar da TypeError verir; yanlış yazılmış anahtar kelime argümanı için 3.13 ile öneri geldi:

python
def selam(ad, soyad):
    return f'{ad} {soyad}'

selam('Ayşe')
# Traceback (most recent call last):
#   File "ornek.py", line 4, in <module>
#     selam('Ayşe')
#     ~~~~~^^^^^^^^
# TypeError: selam() missing 1 required positional argument: 'soyad'
python
print('a,b,c'.split(max_split=1))
# Traceback (most recent call last):
#   File "ornek.py", line 1, in <module>
#     print('a,b,c'.split(max_split=1))
#           ~~~~~~~~~~~~~^^^^^^^^^^^^^
# TypeError: split() got an unexpected keyword argument 'max_split'. Did you mean 'maxsplit'?

Değiştirilemez nesneyi değiştirmeye çalışmak, uzunluğu olmayan bir nesneye len() uygulamak ve hash edilemeyen bir nesneyi kümeye ya da sözlük anahtarına koymak da aynı sınıftadır. Son durum için 3.14 ile mesaj netleşti:

python
kume = set()
kume.add(['liste'])
# Traceback (most recent call last):
#   File "ornek.py", line 2, in <module>
#     kume.add(['liste'])
#     ~~~~~~~~^^^^^^^^^^^
# TypeError: cannot use 'list' as a set element (unhashable type: 'list')
python
t = (1, 2, 3)
t[0] = 9
# TypeError: 'tuple' object does not support item assignment
python
len(5)
# TypeError: object of type 'int' has no len()

Bu son iki örnekte traceback'in yalnızca son satırını gösterdik. Hash edilebilirlik kuralını set ve küme işlemleri, tuple konusunu tuple ve unpacking yazısında anlattık.

AttributeError: olmayan öznitelik ya da metot

AttributeError, bir nesnede bulunmayan bir öznitelik ya da metoda erişildiğinde oluşur. Python 3.15 ile bu mesaj, başka dillerden gelen alışkanlıkları tanıyacak şekilde genişledi: JavaScript'teki push ya da toUpperCase yazıldığında Python karşılığı öneriliyor.

python
sepet = ['elma']
sepet.push('armut')
# Traceback (most recent call last):
#   File "ornek.py", line 2, in <module>
#     sepet.push('armut')
#     ^^^^^^^^^^
# AttributeError: 'list' object has no attribute 'push'. Did you mean '.append'?
python
metin = 'python'
metin.toUpperCase()
# Traceback (most recent call last):
#   File "ornek.py", line 2, in <module>
#     metin.toUpperCase()
#     ^^^^^^^^^^^^^^^^^
# AttributeError: 'str' object has no attribute 'toUpperCase'. Did you mean '.upper'?

En yaygın AttributeError türlerinden biri 'NoneType' object has no attribute ... mesajıdır. Bu, bir değişkenin beklediğiniz nesne yerine None tuttuğunu söyler. Genellikle return içermeyen bir fonksiyonun sonucunu kullanmaktan ya da list.sort() gibi yerinde değiştirip None döndüren bir metodun sonucunu bir değişkene atamaktan kaynaklanır:

python
None.upper()
# Traceback (most recent call last):
#   File "ornek.py", line 1, in <module>
#     None.upper()
#     ^^^^^^^^^^
# AttributeError: 'NoneType' object has no attribute 'upper'

Kendi sınıflarınızda yanlış öznitelik adı kullandığınızda, yakın bir ad yoksa öneri gelmez; bu durumda sınıfın __init__ metodunda hangi adların tanımlandığına bakın. 3.15 ile bir nesnenin içindeki başka bir öznitelik üzerinden erişilebilen ad için '.inner.area' biçiminde iç yol önerisi de eklendi. Sınıf ve öznitelik kavramları için class ve nesne yazısına bakın.

KeyError ve IndexError

KeyError sözlükte olmayan bir anahtara köşeli parantezle erişildiğinde, IndexError bir dizinin sınırları dışındaki bir indekse erişildiğinde oluşur. KeyError mesajı yalnızca eksik anahtarı gösterir:

python
fiyatlar = {'çay': 20}
print(fiyatlar['kahve'])
# Traceback (most recent call last):
#   File "ornek.py", line 2, in <module>
#     print(fiyatlar['kahve'])
#           ~~~~~~~~^^^^^^^^^
# KeyError: 'kahve'
python
gunler = ['Pzt', 'Sal']
print(gunler[5])
# IndexError: list index out of range

Anahtarın olmayabileceği durumlarda fiyatlar.get('kahve', 0) gibi varsayılan değer veren get() metodu ya da in kontrolü kullanın; seçenekler sözlük metotları yazısında. Dilimleme (gunler[2:10]) sınır dışında hata vermez, sessizce kırpılır; yalnızca tek indeksle erişim IndexError verir.

ModuleNotFoundError ve ImportError

ModuleNotFoundError, ImportError sınıfının alt sınıfıdır ve modül hiç bulunamadığında fırlatılır. Üç tipik nedeni vardır: modül adı yanlış yazılmıştır, paket kurulu değildir ya da kurulu olduğu sanal ortam etkin değildir.

python
import reqests
# Traceback (most recent call last):
#   File "ornek.py", line 1, in <module>
#     import reqests
# ModuleNotFoundError: No module named 'reqests'

Modül bulunduğu ama içinden istenen ad bulunamadığında ise ImportError oluşur ve yakın bir ad varsa önerilir:

python
from math import sqr
# ImportError: cannot import name 'sqr' from 'math' (unknown location). Did you mean: 'sqrt'?

Sık yapılan bir hata da betiğinize standart kütüphane modülüyle aynı adı vermektir. Örneğin random.py adlı bir dosyada import random yazarsanız Python kendi dosyanızı içe aktarır. 3.13 ile bu durum için açıklayıcı bir mesaj geldi (dosya yolunu kısalttık):

bash
$ python random.py
Traceback (most recent call last):
  File "C:\...\golge\random.py", line 1, in <module>
    import random
  File "C:\...\golge\random.py", line 2, in <module>
    print(random.randint(5))
          ^^^^^^^^^^^^^^
AttributeError: module 'random' has no attribute 'randint' (consider renaming 'C:\...\golge\random.py' since it has the same name as the standard library module named 'random' and prevents importing that standard library module)

3.15 ile ImportError ve ModuleNotFoundError nesnelerinin repr() çıktısı, oluşturulurken anahtar kelimeyle verildiyse name ve path değerlerini de gösteriyor; tembel içe aktarmadaki döngüler için yeni ImportCycleError sınıfı eklendi. İçe aktarma kuralları modül ve paket import yazısında.

ValueError, ZeroDivisionError, FileNotFoundError ve RecursionError

ValueError, tipi doğru ama değeri uygunsuz bir argümanı gösterir. Kullanıcı girdisini sayıya çevirmek bunun en tanıdık örneğidir; açma (unpacking) sırasında eleman sayısı uyuşmadığında da aynı sınıf kullanılır:

python
print(int('12a'))
# Traceback (most recent call last):
#   File "ornek.py", line 1, in <module>
#     print(int('12a'))
#           ~~~^^^^^^^
# ValueError: invalid literal for int() with base 10: '12a'
python
a, b = [1, 2, 3]
# ValueError: too many values to unpack (expected 2, got 3)
python
print(10 / 0)
# ZeroDivisionError: division by zero
python
open('olmayan.txt')
# FileNotFoundError: [Errno 2] No such file or directory: 'olmayan.txt'

FileNotFoundError, OSError sınıfının alt sınıfıdır ve çoğunlukla göreli yolun programın çalıştığı klasöre göre çözülmesinden kaynaklanır; betiğin bulunduğu klasöre göre değil. Yolları güvenli kurmak için pathlib yazısına bakabilirsiniz. Sonu olmayan özyinelemede ise yorumlayıcı aynı satırın tekrarlarını tek satırda özetler:

python
def sonsuz(n):
    return sonsuz(n + 1)

sonsuz(0)
#   [Previous line repeated 996 more times]
# RecursionError: maximum recursion depth exceeded

RecursionError, RuntimeError sınıfından türer ve özyineleme derinliği sys.getrecursionlimit() sınırını aştığında fırlatılır. Çözüm sınırı artırmak değil, durma koşulunu (base case) eklemektir.

Hata sınıfları arasındaki akrabalık

Yerleşik istisnalar bir sınıf hiyerarşisi oluşturur ve bu hiyerarşiyi bilmek hem mesajları yorumlamayı hem de doğru except bloğunu yazmayı kolaylaştırır. Yukarıda gördüğümüz hataların çoğu birbirinin alt sınıfıdır: ModuleNotFoundError bir ImportError, UnboundLocalError bir NameError, TabError bir IndentationError, o da bir SyntaxError türüdür. UnicodeDecodeError sonunda ValueError ailesine, FileNotFoundError OSError ailesine, RecursionError RuntimeError ailesine bağlanır. Üst sınıfı yakalayan bir except bloğu alt sınıfları da yakalar:

python
print(issubclass(ModuleNotFoundError, ImportError))
# çıktı: True
print(issubclass(UnboundLocalError, NameError))
# çıktı: True
print(issubclass(TabError, SyntaxError))
# çıktı: True
print(issubclass(UnicodeDecodeError, ValueError))
# çıktı: True
print(issubclass(KeyError, LookupError), issubclass(IndexError, LookupError))
# çıktı: True True
print(issubclass(KeyboardInterrupt, Exception))
# çıktı: False

Son satır önemli bir ayrıntıyı gösteriyor: Ctrl-C ile oluşan KeyboardInterrupt, Exception sınıfından değil doğrudan BaseException sınıfından türer. Belgeler bunun, except Exception yazan kodun kullanıcının programı durdurmasını yanlışlıkla engellememesi için yapıldığını açıklar. KeyError ve IndexError ise ortak LookupError üst sınıfını paylaşır; ikisini birden yakalamak istediğinizde bu sınıfı kullanabilirsiniz.

Özet tablo

HataTipik nedenİlk bakılacak yer
SyntaxErrorEksik iki nokta, tırnak, parantez, virgülİşaretlenen satır ve bir önceki satır
IndentationError / TabErrorEksik, fazla ya da karışık girintiEditörün sekme ayarı
NameErrorYazım hatası, import unutmakDid you mean önerisi
UnboundLocalErrorFonksiyonda atamadan önce okumaglobal, nonlocal ya da parametre
TypeErrorYanlış tip, eksik argüman, hash edilemeyen anahtarDeğerlerin type() sonucu
AttributeErrorOlmayan metot, None değerDeğişkenin gerçekte ne tuttuğu
KeyError / IndexErrorOlmayan anahtar, sınır dışı indeksget(), in, len()
ModuleNotFoundErrorYanlış ad, kurulu olmayan paket, etkin olmayan venvHangi python çalışıyor
ValueErrorUygunsuz değer, açma sayısı uyuşmazlığıGirdinin kendisi
FileNotFoundErrorGöreli yol, yanlış klasörÇalışma klasörü

Hata mesajlarıyla çalışırken iyi alışkanlıklar

Hata mesajlarıyla çalışırken iyi alışkanlıklar: Önce son satırı okuyun, Önerileri ciddiye alın, Hatayı sessizce yutmayın, Sürümünüzü bilin
  • Önce son satırı okuyun: istisna sınıfı ve mesaj sorunun türünü söyler; sonra yukarı doğru kendi kodunuza ait en alttaki satırı bulun.
  • Önerileri ciddiye alın: "Did you mean" önerileri yazım hatalarının büyük kısmını doğrudan çözer.
  • Hatayı sessizce yutmayın: except Exception: pass traceback'i yok eder. Beklenen hataları adıyla yakalayın; yöntemler try/except rehberinde.
  • Sürümünüzü bilin: bu yazıdaki önerilerin bir kısmı 3.13, 3.14 ve 3.15 ile geldi; eski sürümlerde mesaj daha kısa olabilir. Yenilikler için Python 3.15 yenilikleri.
  • Kendi istisnalarınıza açıklayıcı mesaj yazın: raise ve özel istisna yazısında add_note() ile ek bilgi eklemeyi anlattık.

Sık Sorulan Sorular

SyntaxError ile diğer hatalar arasındaki fark nedir?

SyntaxError kod çalışmadan önce, ayrıştırma sırasında oluşur; dosyanın hiçbir satırı çalışmaz. Diğer istisnalar çalışma zamanında oluşur ve hata satırına kadar olan kod çalışmış olur.

Hata mesajları Türkçe gösterilebilir mi?

Python'un yerleşik hata mesajları İngilizce üretilir. Bu yazıdaki tablo ve açıklamalar mesajları Türkçe yorumlamanıza yardımcı olmak için hazırlandı.

Öneri satırı neden except içinde print(e) yazınca görünmüyor?

"Did you mean" önerileri, istisna yakalanmadan traceback olarak görüntülendiğinde eklenir; istisna nesnesinin str() değerinin parçası değildir. Bu yüzden print(e) yalnızca temel mesajı yazar.

Traceback'te renkleri nasıl kapatırım?

NO_COLOR ortam değişkenini ayarlayın ya da yalnızca Python için PYTHON_COLORS=0 kullanın. Belgelere göre PYTHON_COLORS, NO_COLOR üzerinde; NO_COLOR da FORCE_COLOR üzerinde önceliklidir.

Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.

İlgili içerikler: Python öğrenme rehberi · try/except hata yönetimi · raise ve özel istisna · Kapsam ve UnboundLocalError · Modül ve import · Python 3.15 yenilikleri