ProgramlamaBackend Python Geliştirici

Python'da özel istisnaların miras alınması nasıl çalışır? Kendi istisnalarınızı oluştururken hangi hususlara dikkat etmelisiniz, geliştiricilerin yaptığı hatalar nelerdir ve istisna işleme ile ilgili tuzaklardan nasıl kaçınılır?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap.

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:

  • Kullanıcı tanımlı istisnalar her zaman Exception'dan miras almalıdır.
  • BaseException türündeki istisnaları yakalamayın (örneğin, KeyboardInterrupt) — bunlar sistem olaylarıdır.
  • İstisnaları daha ince bir işlem için hiyerarşilerde gruplayın.

Kandırma Soruları.

"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ı')

Tipik Hatalar ve Anti Desenler

  • Tür belirtilmeden istisnaların yakalanması (except:)
  • Belirsiz miras ile dış istisnaların içe aktarılması
  • Hatalı sınıf yapılandırıcılarının super().init çağrısı olmadan tanımlanması (mesajın kaybı)

Gerçek Hayattan Bir Örnek

Olumsuz Durum

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:

  • Sistem nadir hatalar nedeniyle "çökmüyordu".

Eksiler:

  • Hata nedenlerini bulmak zordu.
  • Beklenmedik kilitlenmeler, standart kapatma imkansızlığı.

Olumlu Durum

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:

  • Hata işleme açık.
  • Genişletmek ve sürdürmek pratik.

Eksiler:

  • Biraz daha fazla kod ve mimari disiplin gerektirir.