Sorunun Tarihi:
Python'daki istisna sistemi (exceptions) başlangıçta var olmuş ve sınıflar üzerine inşa edilmiştir. Tüm istisna hiyerarşisi temel sınıf olan BaseException'den miras alır. Pratikte, özel istisnalar Exception'dan oluşturulur. Kullanıcı tanımlı istisnaların geliştirilmesi, büyük projelerde önemli bir rol oynar — uygulamanın belirli hatalarını daha net işlemek ve bildirmek için sağlar.
Sorun:
Tüm geliştiriciler BaseException ve Exception arasındaki farkları anlamaz, kendi sınıflarını oluşturmaktan kaçınır, genel catch blokları kullanır, bu da istenmeyen istisnaların (örneğin, SystemExit, KeyboardInterrupt) emilmesine ve zor bulunabilir hatalara yol açar. Sıklıkla istisna sınıfları doğru bir şekilde uygulanmaz — anlamlı bir isim verilmez ve gerekli sınıftan miras alınmaz.
Çözüm:
Kendi istisnalarınızı Exception mirasçıları olarak yazın. Anlamlı isimler kullanarak, temel hataları yakalamaktan kaçının. BaseException'dan değil, sadece Exception veya onun türemiş olanlarından miras alın; ve except: ile her şeyi yakalamaktan kaçının, belirli bir sınıf belirtin.
Kod Örneği:
class MyAppError(Exception): """Uygulama için temel istisna sınıfı""" pass class ConfigFileNotFound(MyAppError): pass try: raise ConfigFileNotFound('Yapılandırma dosyası bulunamadı!') except ConfigFileNotFound as e: print(f'Hata: {e}')
Anahtar Özellikler:
"except:" kullanarak tüm istisnaları yakalamanın tehlikesi nedir?
Bu blok, sistem istisnalarını — KeyboardInterrupt, SystemExit — bile yakalar; bu da Ctrl+C ile programın düzgün bir şekilde sonlandırılmasını imkansız hale getirir ve kritik durumlarda "takılma" ya neden olur. Temel sistem olaylarını atlamak için "except Exception:" yazmalısınız.
Kendi istisnanızı BaseException'dan miras alabilir misiniz?
Teknik olarak mümkündür, ancak kesinlikle önerilmez — bu tür istisnalar zor bulunur, standart Exception işleyicilerini atlatır ve bu genellikle uygulamada yakalanamayan hatalara yol açar.
Kullanıcı tanımlı istisnalar yerine ValueError veya TypeError kullanmak doğru mu?
Küçük betiklerde uygun olabilir, ancak büyük projelerde kendi anlamlı istisnalarınızı oluşturmak daha iyidir. Bu, hataların üst seviyelerdeki uygulama üzerinde daha hızlı bir şekilde teşhis edilmesini ve işlenmesini hızlandırır.
# Yanlış: raise ValueError('Uygulama için spesifik bir şey') # İyi: class MyAppValueError(MyAppError): pass raise MyAppValueError('Uygulama bağlamıyla hatanın açıklaması')
Büyük bir projede, sistem istisnalarını yakalayan bir global try/except: bloğu vardı. Bir dizi hata (örneğin, SystemExit) günlüğe yazılmadı, uygulama beklenmeyen duruma geçti, yöneticiler semptomları uzun süre aradı.
Artılar:
Eksiler:
Kendi hata sınıfları belirlendi, her yerde yalnızca "except Exception: ..." ve kullanıcı tanımlı istisnalar için ayrı işleyiciler kullanıldı.
Artılar:
Eksiler: