İstisnalar, modüller ve sistematik hata ayıklama
Bir programın doğru sözdizimine sahip olması, her durumda sorunsuz çalışacağı anlamına gelmez. Dosya bulunamayabilir, metin sayıya dönüştürülemeyebilir, beklenen anahtar sözlükte olmayabilir veya bir hesap sıfıra bölme yapabilir.
Bu hafta istisna (exception) kavramını, try/except ile belirli çalışma zamanı sorunlarını ele almayı, standart kütüphane modüllerini kullanmayı ve hata ayıklamayı daha sistematik bir sürece dönüştürmeyi öğreneceğiz.
Bu hafta neleri yapabilmelisiniz?
Bölümün sonunda:
- söz dizimi hatası ile çalışma zamanı hatasını ayırt edebilmeli,
- istisnanın ne olduğunu açıklayabilmeli,
try/exceptile belirli bir hata türünü yakalayabilmeli,- gereğinden geniş
exceptkullanımının neden sorunlu olduğunu açıklayabilmeli, - bir traceback’in en azından hata türünü ve ilgili satırı bulmak için nasıl okunacağını açıklayabilmeli,
- standart kütüphaneden bir modülü
importile kullanabilmeli, - kendi modülünüzü oluşturma fikrini açıklayabilmeli,
- main guard yapısının temel amacını açıklayabilmeli,
- bir hatayı yeniden üretme, küçültme, tahmin kurma ve doğrulama adımlarıyla sistematik biçimde inceleyebilmelisiniz.
Hata türlerini ayırmak
Başlangıç düzeyinde üç hata sınıfını ayırmak yararlıdır.
Söz dizimi hatası
Python kodun yapısını okuyamaz:
if puan >= 60
print("Geçti")
İki nokta eksiktir ve SyntaxError oluşur.
Çalışma zamanı hatası
Kod sözdizimsel olarak geçerlidir; ancak çalışırken sorun çıkar:
sayi = int("abc")Burada ValueError oluşur.
Başka örnekler:
10 / 0ZeroDivisionError
liste = [1, 2]
liste[5]IndexError
Mantık hatası
Program çalışır, fakat yanlış sonuç üretir:
def daire_cevresi(yaricap):
return 3.14 * yaricapProgram hata vermeyebilir; ancak çevre formülü eksiktir. Bu tür sorunları Python otomatik olarak her zaman fark edemez.
Hata ayıklamada ilk soru “program çalışıyor mu?” değil, “sorun hangi sınıfa ait?” olabilir. Söz dizimi, çalışma zamanı ve mantık hataları farklı inceleme yolları gerektirir.

İstisna nedir?
Python çalışırken olağan akışı sürdüremediği bir durumla karşılaştığında istisna oluşturabilir.
Örneğin:
int("on")Python "on" metnini tam sayıya çeviremez ve ValueError üretir.
İstisna yalnızca “program bozuldu” bilgisi değildir. Hata türü, sorunun niteliği hakkında ipucu verir.
try / except
Belirli bir işlemin hata üretme ihtimali varsa ve bu durumu anlamlı biçimde ele alabiliyorsak try/except kullanabiliriz:
metin = "42"
try:
sayi = int(metin)
print("Sayı:", sayi)
except ValueError:
print("Geçerli bir tam sayı değil")metin = "abc" olduğunda dönüşüm başarısız olur ve except ValueError bloğu çalışır.

try ve except ValueError akışının nasıl ilerlediğini gösteren hata yönetimi şeması.Tahmin et — hangi blok çalışır?
Önce "75" ile sonucu tahmin edin. Sonra girdi_metni değerini "yetmis" yapıp tekrar çalıştırın.
Tarayıcı hücresinde input() kullanmıyoruz; kullanıcıdan gelmiş olabilecek metni değişkenle simüle ediyoruz.
Alıştırma — dönüşüm hatasını ele alın
Aşağıdaki kod "abc" değerinde hata veriyor:
Kodu try/except ValueError kullanacak biçimde değiştirin. Geçersiz metinde:
Geçerli sayı değil
yazdırılsın.
try: içinde dönüşümü yapın; except ValueError: içinde hata mesajını yazdırın.
girdi_metni = "abc"
try:
sayi = int(girdi_metni)
print(sayi)
except ValueError:
print("Geçerli sayı değil")Belirli hata türünü yakalamak
Şu kullanım teknik olarak birçok hatayı yakalayabilir:
try:
...
except:
...Fakat hangi sorunun oluştuğunu gizleyebilir.
Örneğin amaç yalnızca sayı dönüşüm hatasını yönetmekse:
try:
sayi = int(metin)
except ValueError:
...daha açıklayıcıdır.
“Program hiçbir zaman hata vermesin” diye her şeyi geniş bir except ile kapatmak hata ayıklamayı zorlaştırabilir. Yalnızca anlamlı biçimde ele alabildiğiniz ve beklediğiniz hata türlerini yakalayın.
Birden fazla hata türü
Aşağıdaki fonksiyon metni sayıya dönüştürüp bölme yapıyor:
def bol(metin, bolen):
sayi = int(metin)
return sayi / bolenİki farklı çalışma zamanı sorunu olabilir:
metinsayısal değilseValueError,bolen0iseZeroDivisionError.
Bunları ayrı ele alabiliriz:
try:
sonuc = bol("20", 0)
print(sonuc)
except ValueError:
print("Metin sayıya dönüştürülemedi")
except ZeroDivisionError:
print("Sıfıra bölme yapılamaz")Ayrı mesajlar sorunun nedenini görünür tutar.
İstisna mı, koşul mu?
Her kontrol için istisna gerekmez.
Örneğin puanın 0 ile 100 arasında olması normal bir iş kuralıdır:
if 0 <= puan <= 100:
...
else:
...Metnin int() ile dönüştürülememesi ise dönüşüm sırasında oluşan çalışma zamanı problemidir:
try:
puan = int(girdi_metni)
except ValueError:
...Bu ayrım şu soruyla düşünülebilir:
Bu durum normal karar mantığının bir parçası mı?
Yoksa yapılan işlem beklenen türde veriyi işleyemedi mi?
Traceback okumak
Bir istisna yakalanmazsa Python hata iz dökümü (traceback) gösterir.
Örnek:
Traceback (most recent call last):
File "rapor.py", line 12, in <module>
toplam = fiyat_hesapla("abc")
File "rapor.py", line 5, in fiyat_hesapla
fiyat = float(metin)
ValueError: could not convert string to float: 'abc'
Başlangıçta traceback’i şu sırayla okuyabilirsiniz:
- En alttaki hata türünü bulun:
ValueError. - Mesajı okuyun: hangi değer dönüştürülemedi?
- Kendi kodunuzdaki ilgili satırı bulun.
- O satıra hangi değerlerin geldiğini kontrol edin.
- Sorunun kaynağını daha küçük örnekle yeniden üretin.
Traceback’teki en uzun veya en teknik satırdan başlamanız gerekmez. Hata türü ve kendi kodunuzdaki son ilgili satır çoğu zaman iyi başlangıç noktalarıdır.
Sistematik hata ayıklama
Rastgele satır değiştirmek yerine küçük bir süreç kullanalım.
Sorunu yeniden üret
Hata hangi girdiyle oluşuyor?
"abc" girildiğinde ValueError oluşuyor.
Beklenen davranışı yaz
Geçersiz metinde kullanıcıya açıklayıcı mesaj verilmeli.
Problemi küçült
Büyük program yerine yalnızca sorunlu dönüşümü deneyin:
int("abc")Değerleri gözlemle
Gerekirse geçici çıktı ekleyin:
print("Dönüştürülecek değer:", girdi_metni)Hipotez kur ve tek değişiklik yap
Sorun int() dönüşümünden kaynaklanıyor.
Yeniden doğrula
Hem hatalı hem geçerli örneği deneyin.
Bu süreç hata ayıklamayı “tahmin ederek kod değiştirme” işinden ölçülebilir bir incelemeye dönüştürür.
Modül nedir?
Python kodunu başka dosyalara ve yeniden kullanılabilir bileşenlere ayırmak için modül kavramı kullanılır.
Standart kütüphaneden örnek:
import math
print(math.sqrt(81))
print(math.pi)math Python ile birlikte gelen standart kütüphane modüllerinden biridir.
Başka örnek:
from datetime import date
bugun = date.today()
print(bugun)Bu hafta modül seçeneklerini ezberlemiyoruz. Ana fikir:
İhtiyacımız olan bazı işlevler Python’ın standart kütüphanesinde hazır modüller olarak bulunur.
Tahmin et ve çalıştır — math
İkinci çıktı, sonucu iki ondalık basamağa yuvarlayarak daha okunur hâle getirir.
Kendi modülümüz
Aynı dizinde hesaplar.py dosyamız olduğunu düşünelim:
def kdv_hesapla(tutar, oran):
return tutar * oran
def indirimli_fiyat(fiyat, oran):
return fiyat - fiyat * oranBaşka bir dosyada:
import hesaplar
print(hesaplar.kdv_hesapla(500, 0.20))veya:
from hesaplar import kdv_hesapla
print(kdv_hesapla(500, 0.20))Bu yapı büyük programlarda fonksiyonları anlamlı dosyalara ayırmamıza yardım eder.
Main guard
Bir Python dosyası hem doğrudan çalıştırılabilir hem de başka dosyadan modül olarak içe aktarılabilir.
Sık kullanılan kalıp:
def main():
print("Program başladı")
if __name__ == "__main__":
main()Bu yapıya main guard denir.
Temel fikir:
- dosya doğrudan çalıştırılırsa
main()çağrılır, - dosya modül olarak içe aktarılırsa bu çağrı otomatik çalışmaz.
Şimdilik __name__ mekanizmasının bütün ayrıntılarını bilmemiz gerekmiyor.
Main guard, Python anahtar sözcüğü değildir; __name__ özel değişkeni üzerinden kurulan yaygın bir Python kalıbıdır.
Alıştırma — modül fonksiyonunu kullanın
math modülünü kullanarak bir dik üçgende iki dik kenardan hipotenüsü hesaplayan fonksiyonu tamamlayın.
Formül:
√(a² + b²)
Beklenen sonuç 5.0dır.
math.sqrt(a ** 2 + b ** 2) ifadesini döndürebilirsiniz.
import math
def hipotenus(a, b):
return math.sqrt(a ** 2 + b ** 2)
print(hipotenus(3, 4))Hata ayıklamada fonksiyon ve assert
Bir mantık hatasını küçük fonksiyon testleriyle yakalayabiliriz:
def indirimli_fiyat(fiyat, oran):
return fiyat * oran
assert indirimli_fiyat(100, 0.20) == 80Bu assert başarısız olur. Fonksiyonun “indirimli fiyat” yerine “indirim miktarı” döndürdüğünü fark ederiz.
Doğrusu:
def indirimli_fiyat(fiyat, oran):
return fiyat - fiyat * oranBu örnek önemli bir noktayı gösterir: istisna yoktur; hata beklenen davranış ile gerçek sonuç arasındaki farktan bulunur.
Üret — güvenli puan dönüştürme
puani_coz(metin) fonksiyonu yazın.
Kurallar:
- Metin tam sayıya dönüştürülemiyorsa
Nonedöndürsün. - Sayı
0ile100arasındaysa sayıyı döndürsün. - Sayı aralık dışındaysa
Nonedöndürsün. - Fonksiyon içinde
print()kullanılmasın.
Başlangıç:
Beklenen:
85
None
None
try içinde puan = int(metin) yapın. except ValueError: durumunda return None; dönüşüm başarılıysa aralık kontrolü yapın.
def puani_coz(metin):
try:
puan = int(metin)
except ValueError:
return None
if 0 <= puan <= 100:
return puan
return None
print(puani_coz("85"))
print(puani_coz("abc"))
print(puani_coz("120"))Hata ayıklama kontrol listesi
Bir programda sorun olduğunda:
- Hata türü nedir: söz dizimi, çalışma zamanı, mantık?
- Sorunu aynı girdiyle yeniden üretebiliyor muyum?
- Beklenen sonuç nedir?
- Sorunu daha küçük bir örneğe indirebilir miyim?
- Traceback hangi hata türünü ve hangi satırı gösteriyor?
- O satırdaki değişkenlerin değerleri nedir?
- Tek bir hipotezi sınayacak küçük değişiklik yapabilir miyim?
- Düzeltme sonrası hem sorunlu hem normal örneği yeniden denedim mi?
Bu süreç, 14. haftadaki bütünleştirici uygulamada özellikle önemli olacaktır.
Bölüm özeti
Bu hafta programlarımızın hata durumlarını daha bilinçli ele almaya başladık.
- Söz dizimi hatası kodun yapısında, çalışma zamanı hatası yürütme sırasında, mantık hatası ise sonuç davranışında ortaya çıkar.
- İstisna, Python’ın yürütme sırasında olağan akışı sürdüremediği durumu temsil eder.
try/except, beklenen belirli istisnaları anlamlı biçimde ele almaya yarar.- Geniş
exceptkullanımı gerçek hataları gizleyebilir. - Traceback’te hata türü ve kendi kodunuzdaki ilgili satır iyi başlangıç noktalarıdır.
- Hata ayıklama yeniden üretme, küçültme, gözlemleme, hipotez kurma ve doğrulama süreci olarak ele alınabilir.
- Standart kütüphane modülleri
importile kullanılabilir. - Kendi Python dosyalarımız da modül olabilir.
- Main guard, dosyanın doğrudan çalıştırılması ile modül olarak içe aktarılması davranışlarını ayırmaya yardım eder.
Kendinizi kontrol edin
SyntaxErrorileValueErrorarasındaki temel fark nedir?except ValueError:neden tek başınaexcept:kullanımından daha açıklayıcıdır?- Puanın
0–100aralığında olması neden çoğunlukla koşulla kontrol edilir? - Traceback okurken başlangıçta hangi iki bilgiyi aramak yararlıdır?
- Mantık hatası neden her zaman istisna üretmez?
import mathne yapar?- Kendi modülünüzü oluşturmanın temel amacı nedir?
- Main guard hangi iki kullanım biçimini ayırmaya yardım eder?
- Hata ayıklamada “tek değişiklik yapıp yeniden denemek” neden yararlıdır?
Bir sonraki bölümde yeni kavram eklemeyeceğiz. İlk 13 haftadaki araçları birlikte kullanarak küçük bir bütünleştirici mikro uygulama geliştireceğiz.