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
BaseException ├── SystemExit ├── KeyboardInterrupt ├── GeneratorExit └── Exception ├── ArithmeticError │ ├── ZeroDivisionError │ └── FloatingPointError ├── LookupError │ ├── IndexError │ └── KeyError ├── OSError │ ├── FileNotFoundError │ └── PermissionError └── ... (diğerleri)
Neden Exception Handling Kullanmalıyız?
Programın beklenmedik şekilde sonlanmasını önler
Kullanıcı dostu hata mesajları sunar
Kaynak sızıntılarını önler (dosya, ağ bağlantıları vb.)
Hata ayıklamayı kolaylaştırır
Temel Try-Except Kullanımı
Basit Örnek
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
try: # Riskli kod except (TypeError, ValueError) as e: print(f"Hata oluştu: {e}")
Gelişmiş Exception Teknikleri
1. Else Bloğu Kullanımı
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
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+)
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ı
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çıklama | Yaygın Nedeni |
---|---|---|
IndexError | Geçersiz indeks | liste[10] (liste 5 elemanlıysa) |
KeyError | Geçersiz dictionary key | sozluk["olmayan_key"] |
AttributeError | Geçersiz nitelik | None.nitelik |
TypeError | Yanlış tip işlemi | "string" + 123 |
ImportError | Modül bulunamadı | import olmayan_modul |
Exception Handling En İyi Uygulamaları
1. Spesifik Exception'ları Yakalayın
# Kötü: try: # Tüm kod except: pass # İyi: try: # Belirli kod except FileNotFoundError: # Özel işlem
2. Exception'ları Loglayın
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
with open("dosya.txt") as f: icerik = f.read() # Otomatik kapanır
4. Exception Mesajlarını Açık Yazın
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
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
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
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!
# 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
# 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?
class MyError(Exception): def __init__(self, value): self.value = value def __str__(self): return f"Özel hata: {self.value}" raise MyError("özel mesaj")