Dosyalar, istisnalar ve sistematik hata ayıklama

Gerçek programlar yalnızca doğru girdilerle çalışmaz. Dosya bulunmayabilir, kullanıcı sayı yerine metin girebilir, kayıt eksik olabilir veya program mantıksal olarak yanlış sonuç üretebilir. Bu hafta temel dosya işlemlerini ve istisnaları kullanacak; hata mesajını rastgele değişiklik yapma nedeni değil, teşhis kanıtı olarak okuyacağız.

Bu hafta neleri yapabilmelisiniz?

  • with open(...) ile metin dosyası okuyup yazabilmeli,
  • satır sonlarını ve basit ayırıcıyla veri işlemeyi yönetebilmeli,
  • söz dizimi, çalışma zamanı ve mantık hatalarını ayırabilmeli,
  • try / except yapısını sınırlı ve anlamlı biçimde kullanabilmeli,
  • hata iz dökümünün (traceback) en alttaki hata satırını ve çağrı zincirini okuyabilmeli,
  • hatayı küçük bir örnekle yeniden üretebilmelisiniz.

Dosyayı güvenli biçimde açmak

with open("notes.txt", "r", encoding="utf-8") as file:
    content = file.read()

print(content)

with bloğu tamamlandığında dosya kapatılır. Elle close() çağrısını unutma riski azalır.

Yazmak için:

with open("report.txt", "w", encoding="utf-8") as file:
    file.write("Rapor hazır\n")

Web/Pyodide ortamında sanal dosya sistemi kullanılabildiği için küçük dosya deneylerini doğrudan yapabiliriz:

Satır satır okuma

Bu örnek gerçek CSV ayrıntılarını öğretmiyor; yalnızca dosyadan gelen metni parçalara ayırma fikrini gösteriyor.

Üç hata sınıfını ayırın

Söz dizimi hatası

Python kodun yapısını okuyamaz:

if score > 50
    print("Geçti")

Çalışma zamanı hatası

Kod okunur, ancak yürütme sırasında sorun oluşur:

score = int("seksen")

Mantık hatası

Program çalışır fakat yanlış sonuç üretir:

# Yüzde 20 indirim yapmak isterken:
final = price * 1.20

Mantık hataları çoğu zaman istisna üretmediği için test ve örnek girdiyle doğrulama gerektirir.

try / except: hatayı saklamak için değil yönetmek için

except Exception: yazarak her şeyi yakalamak başlangıçta rahat görünebilir; ancak programlama hatalarını da saklayabilir. Beklediğiniz hata türünü mümkün olduğunca açık yazın.

try/except/else/finally akışında hatalı ve hatasız yolların ayrılması.
WarningSessizce yutmayın
try:
    risky_operation()
except Exception:
    pass

bu biçim, neyin yanlış gittiğini görünmez hâle getirir. Öğrenme aşamasında hata mesajını görmek çoğu zaman daha değerlidir.

Hata iz dökümü (traceback) nasıl okunur?

Örnek:

Traceback (most recent call last):
  File "app.py", line 12, in <module>
    total = calculate(data)
  File "app.py", line 5, in calculate
    return 100 / data["count"]
ZeroDivisionError: division by zero

İlk bakılacak yer en alttaki satırdır: hata türü ZeroDivisionError. Sonra hemen üstte hatanın oluştuğu kod satırını bulun. Daha yukarıdaki satırlar o noktaya nasıl gelindiğini gösterir.

Bir dosyadan okunan sıfır değerinin bölme hatasına dönüşmesi ve traceback içinde hatalı satırın gösterilmesi.

Hata ayıklama döngüsü

Bu derste şu kısa döngüyü kullanacağız:

  1. Yeniden üret: Hata hangi girdide kesin oluşuyor?
  2. Daralt: En küçük hangi kod parçası hâlâ hatayı üretiyor?
  3. Kanıt topla: traceback, print, type, ara değerler.
  4. Hipotez kur: Sorunun nedeni ne olabilir?
  5. Tek değişiklik yap: Birden çok rastgele değişiklik yapma.
  6. Yeniden doğrula: Hata gitti mi? Başka durum bozuldu mu?

Bu süreç Nesne II dersinde debugger, logging ve testlerle daha sistematik hâle gelecektir.

Alıştırma — Doğru hata türünü yakala

except ValueError:

Alıştırma — Mantık hatasını bul

Program hatasız çalışıyor. Ancak yüzde 20 indirim için beklenen sonuç 80 olmalı. Hatanın neden istisna üretmediğini açıklayın ve fonksiyonu düzeltin.

Alıştırma — Dosya verisini doğrula

Aşağıdaki sanal dosyada bir bozuk kayıt var:

Kodu önce okuyun; hangi satırın atlanacağını tahmin edin. Daha sonra bozuk satırın yerine 30 yazarak tekrar çalıştırın.

Küçük üretim görevi — Dayanıklı kayıt okuyucu

name,score biçiminde dört satırlık sanal dosya oluşturun. Bir satırda geçersiz puan bulunsun. Program:

  • geçerli kayıtları listeye eklesin,
  • geçersiz satırı açık mesajla bildirsin,
  • geçerli puanların ortalamasını yazsın,
  • hiç geçerli kayıt yoksa sıfıra bölme hatasına düşmesin.

Bu görevde hedef “her hatayı yakalamak” değil, beklenen veri hatalarını bilinçli sınırda yönetmektir.

Python köprüsünün kapanışı

İlk beş haftada Python’ın temel araçlarını hızlı biçimde kurduk. Bundan sonra dersin odağı değişiyor. Artık soru “Python’da döngü nasıl yazılır?” değil, “Bir problem alanındaki durumu ve davranışı hangi nesne üstlenmeli?” olacaktır.

Elimizde şu beceriler var:

  • değer ve türlerle çalışma,
  • kontrol akışı,
  • koleksiyonlar ve referans sezgisi,
  • fonksiyonla sorumluluk ayırma,
  • modül, dosya ve hata yönetimi.

Bunların tamamı OOP’nin ham malzemesidir.

Kendinizi kontrol edin

  1. with open(...) neden tercih edilir?
  2. Mantık hatası neden traceback üretmeyebilir?
  3. ValueError ile FileNotFoundError aynı tür sorun mudur?
  4. except Exception: pass neden kötü bir teşhis alışkanlığıdır?
  5. Hata ayıklamada “en küçük yeniden üretim” ne sağlar?

Bu haftadan akılda kalması gerekenler

  • Hata mesajı bir kanıttır; rastgele değişiklik çağrısı değildir.
  • Beklenen istisnayı dar biçimde yakalayın.
  • Çalışan kod doğru kod olmak zorunda değildir.
  • Dosya ve dış girdiler güvenilmez olabilir; doğrulamayı tasarımın parçası yapın.
  • Gelecek haftadan itibaren bu kuralları nesnelerin içinde korumayı öğreneceğiz.
Back to top