Giriş

Python'da program akışını kesintiye uğratan beklenmedik hatalara exception (istisna) denir. Bu makalede, Python exception'larının ne olduğunu, nasıl yönetileceğini ve en iyi uygulamaları detaylı şekilde inceleyeceğiz. Örnek kodlarla zenginleştirilmiş bu rehber, hem yeni başlayanlar hem de profesyonel geliştiriciler için kapsamlı bir kaynak niteliğindedir.


Exception Nedir?

Python'da exception'lar, program çalışırken ortaya çıkan runtime hatalarını temsil eder. SyntaxError'dan farklı olarak, bu hatalar kod yazımı sırasında değil, çalışma zamanında (runtime) ortaya çıkar.

Temel Exception Hiyerarşisi

text
BaseException
 ├── SystemExit
 ├── KeyboardInterrupt
 ├── GeneratorExit
 └── Exception
      ├── ArithmeticError
      │    ├── ZeroDivisionError
      │    └── FloatingPointError
      ├── LookupError
      │    ├── IndexError
      │    └── KeyError
      ├── OSError
      │    ├── FileNotFoundError
      │    └── PermissionError
      └── ... (diğerleri)

Neden Exception Handling Kullanmalıyız?

  1. Programın beklenmedik şekilde sonlanmasını önler

  2. Kullanıcı dostu hata mesajları sunar

  3. Kaynak sızıntılarını önler (dosya, ağ bağlantıları vb.)

  4. Hata ayıklamayı kolaylaştırır


Temel Try-Except Kullanımı

Basit Örnek

python
try:
    sayi = int(input("Bir sayı girin: "))
    print(10 / sayi)
except ValueError:
    print("Geçersiz sayı formatı!")
except ZeroDivisionError:
    print("Sıfıra bölme hatası!")

Çoklu Exception Yakalama

python
try:
    # Riskli kod
except (TypeError, ValueError) as e:
    print(f"Hata oluştu: {e}")

Gelişmiş Exception Teknikleri

1. Else Bloğu Kullanımı

python
try:
    dosya = open("veri.txt", "r")
except OSError:
    print("Dosya açılamadı")
else:
    # Hata oluşmazsa çalışır
    icerik = dosya.read()
    dosya.close()

2. Finally Bloğu ile Kaynak Temizleme

python
try:
    db = connect_to_database()
    # Veritabanı işlemleri
except DatabaseError as e:
    print(f"Veritabanı hatası: {e}")
finally:
    db.close()  # Her durumda çalışır

3. Exception Zincirleme (Python 3+)

python
try:
    import olmayan_modul
except ImportError as e:
    raise RuntimeError("Modül yükleme başarısız") from e

Özel Exception Tanımlama

Custom Exception Sınıfı

python
class HataliDeger(Exception):
    """Geçersiz değer girildiğinde fırlatılır"""
    
    def __init__(self, deger, mesaj="Geçersiz değer"):
        self.deger = deger
        self.mesaj = mesaj
        super().__init__(self.mesaj)

def karekök_al(x):
    if x < 0:
        raise HataliDeger(x, "Negatif sayıların karekökü alınamaz")
    return x ** 0.5

Python'da Sık Karşılaşılan Exception'lar

Exception TürüAçıklamaYaygın Nedeni
IndexErrorGeçersiz indeksliste[10] (liste 5 elemanlıysa)
KeyErrorGeçersiz dictionary keysozluk["olmayan_key"]
AttributeErrorGeçersiz nitelikNone.nitelik
TypeErrorYanlış tip işlemi"string" + 123
ImportErrorModül bulunamadıimport olmayan_modul

Exception Handling En İyi Uygulamaları

1. Spesifik Exception'ları Yakalayın

python
# Kötü:
try:
    # Tüm kod
except:
    pass

# İyi:
try:
    # Belirli kod
except FileNotFoundError:
    # Özel işlem

2. Exception'ları Loglayın

python
import logging
logging.basicConfig(filename='app.log')

try:
    kritik_islem()
except Exception as e:
    logging.exception("Hata oluştu: ")
    raise  # Yeniden fırlat

3. Context Manager Kullanın

python
with open("dosya.txt") as f:
    icerik = f.read()  # Otomatik kapanır

4. Exception Mesajlarını Açık Yazın

python
raise ValueError("Geçersiz değer: parametre 1-10 arasında olmalıdır")

Gerçek Dünya Senaryoları

1. API İsteklerinde Hata Yönetimi

python
import requests
from requests.exceptions import RequestException

try:
    response = requests.get("https://api.example.com/data", timeout=5)
    response.raise_for_status()
    data = response.json()
except RequestException as e:
    print(f"API isteği başarısız: {e}")
    data = {"varsayilan": "deger"}

2. Veritabanı İşlemlerinde Transaction Yönetimi

python
import psycopg2
from psycopg2 import DatabaseError

conn = None
try:
    conn = psycopg2.connect("dbname=test user=postgres")
    cur = conn.cursor()
    cur.execute("INSERT INTO users VALUES (%s)", ("ahmet",))
    conn.commit()
except DatabaseError as e:
    if conn:
        conn.rollback()
    print(f"Veritabanı hatası: {e}")
finally:
    if conn:
        conn.close()

3. Çoklu Dosya İşlemleri

python
import os

files = ["data1.txt", "data2.txt", "data3.txt"]
success = 0

for file in files:
    try:
        if not os.path.exists(file):
            raise FileNotFoundError(f"{file} bulunamadı")
        with open(file) as f:
            process(f.read())
        success += 1
    except Exception as e:
        print(f"{file} işlenirken hata: {e}")

print(f"Başarılı işlem: {success}/{len(files)}")

Performans Optimizasyonu

Exception'lar Pahalıdır!

python
# Kötü:
try:
    for i in range(1000000):
        liste[i]
except IndexError:
    pass

# İyi:
length = len(liste)
for i in range(min(1000000, length)):
    liste[i]

Sonuç

Python'da etkili exception handling için:

✔ Spesifik exception'ları yakalayın
✔ Kaynak temizliğini garanti altına alın
✔ Anlamlı hata mesajları kullanın
✔ Loglama sistemleri entegre edin

python
# Unutmayın: İyi hata yönetimi, profesyonel kodun ayırt edici özelliğidir
try:
    run_application()
except Exception as e:
    log_error(e)
    show_user_friendly_message()
finally:
    cleanup_resources()

Sık Sorulan Sorular (SSS)

1. Tüm exception'ları yakalamak doğru mu?

Hayır! Sadece beklenen ve işlenebilir exception'ları yakalayın. Sistem çıkışı (SystemExit) gibi exception'lar genellikle yakalanmamalıdır.

2. Assert ile exception arasındaki fark?

assert geliştirme sırasında doğrulama içindir (-O flag'i ile devre dışı bırakılabilir). Exception'lar runtime hataları içindir.

3. Python'da exception performans etkisi nasıl?

Exception'lar normal akış kontrolünden ~4x daha yavaştır. Sık tekrarlanan döngülerde if-else tercih edin.

4. Exception mesajlarını nasıl özelleştiririm?

python
class MyError(Exception):
    def __init__(self, value):
        self.value = value
    def __str__(self):
        return f"Özel hata: {self.value}"

raise MyError("özel mesaj")