Menu

Python İstisnaları: try, except, else, finally ve raise

Python'da hataları nasıl ele alırsın — try/except/finally, belirli istisnaları yakalama, kendi istisnalarını fırlatma ve bir hatayı ne zaman yayılmaya bırakmalı.

Hatalar Aslında Suratsız Değerlerdir

Python'da bir şey yanlış gittiğinde — sıfıra bölmek, eksik bir dosya okumak, bozuk bir sayı ayrıştırmak — runtime bir istisna nesnesi oluşturur ve bir şey onu yakalayana dek çağrı yığınını geri sarar. Hiçbir şey yakalamazsa programın sonlanır ve bir traceback yazdırır.

İstisnalar başlı başına kötü değildir. Python'un "bu işlemi sürdüremiyorum; işte nedeni" sinyalidir. Senin işin ise, durum bazında, hangilerinden toparlanmayı bildiğine ve hangilerinin yukarı çıkmasına izin vermen gerektiğine karar vermek.

Temel Şekil

main.py
Output
Click Run to see the output here.
  • try: riskli kodun bloğunu açar.
  • except ValueError:, o belirli istisna try içinde fırlatılırsa onu yakalar.
  • Hiçbir istisna tetiklenmezse except tamamen atlanır.

Parçacığı 42 ile çalıştır — çalışır. hello ile çalıştır — handler çalışır.

Belirli İstisnaları Yakalama

Python'un bir istisna tipi hiyerarşisi vardır. Sık karşılaşacağın birkaçı:

  • ValueError — değer bir şekilde yanlıştı (int("abc"), aralık dışı argümanlar).
  • TypeError — yanlış tip kullanıldı ("hi" + 3).
  • KeyError — dict anahtarı bulunamadı.
  • IndexError — sıralı bir dizinin indeksi aralık dışıydı.
  • FileNotFoundError — dosya yok.
  • ZeroDivisionError — sıfıra bölmeyi denedin.
  • AttributeError — nesne istenen özniteliğe sahip değil.

Nasıl toparlayacağını bildiğin belirli olanı yakala:

main.py
Output
Click Run to see the output here.

Bir tuple geçerek tek bir cümlede birden fazla istisnayı yakalayabilirsin:

main.py
Output
Click Run to see the output here.

as e'ye dikkat. Bu, istisna nesnesini e'ye bağlar; böylece mesajını veya özniteliklerini inceleyebilirsin.

Her Şeyi Yakalamaktan Kaçın

Çıplak bir except:, KeyboardInterrupt (Ctrl-C'n) ve sistem düzeyindeki çıkışlar dahil gerçekten her şeyi yakalar. Kullanma.

except Exception: biraz daha iyidir ama yine tehlikelidir — öngörmediğin hataları yutar ve sorunların gerçek kaynağını gizler:

# Çok iyi bir sebep olmadan bunu yapma.
try:
    do_something()
except Exception:
    pass

Doğru hamle neredeyse her zaman toparlamayı bildiğin belirli istisnayı yakalamaktır. Beklemediğin bir istisna programının tepesine ulaşırsa, traceback sana tam olarak neyin yanlış gittiğini söyler — bu bir bug değil, bir özelliktir.

else ve finally

try deyiminin iki opsiyonel cümlesi daha vardır:

  • else, try bloğu istisna fırlatmadan bittiyse çalışır.
  • finally, istisna olsa da olmasa da çalışır.
main.py
Output
Click Run to see the output here.

else, "yalnızca başarı" kodu için en temiz yerdir — try bloğunun gerçekten başarısız olabilen kısmından fazlasını yapmasını istemezsin. finally, try başarısız olsa bile çalışması gereken temizlik içindir: bir kaynağı kapatma, bir kilidi bırakma, bir durumu geri yükleme.

İstisnaları Kendi Fırlatmak

Kendi kodunda bir hata sinyali vermek için raise kullan:

main.py
Output
Click Run to see the output here.

Olan bitene uyan bir istisna tipi seç. Kendi sınıfını tanımlamadan önce yerleşik olanlara uzan — ValueError, TypeError, FileNotFoundError.

Kendi İstisnanı Tanımlamak

Yerleşik olanlar anlamı yakalamadığında özel bir istisna tanımla:

main.py
Output
Click Run to see the output here.

Exception'dan (veya daha belirli bir yerleşikten) kalıt al ve sınıfa bir docstring ver. Genelde ihtiyacın olan bu kadardır. Özel istisnalar, çağıranların yalnızca kendi alanlarında anlamlı olan hatayı yakalamasına izin verir.

raise ... from ...: Zincirlenmiş İstisnalar

Bir istisna başkasını tetiklediğinde zinciri koru:

main.py
Output
Click Run to see the output here.

from e, orijinal hatayı iliştirir. Traceback yazıldığında Python ikisini de gösterir — yüzeye çıkan ConfigError ve buna yol açan FileNotFoundError. Bu tür bir iz, hata ayıklarken paha biçilmezdir.

Context Manager: Temizliğin Daha Temiz Yolu

finally yeterlidir ama dosyalar gibi kaynaklar için bir context manager (with'in kullandığı) neredeyse her zaman daha iyidir:

# finally sürümü
f = open("data.txt")
try:
    data = f.read()
finally:
    f.close()

# with sürümü
with open("data.txt") as f:
    data = f.read()

İkisi de güvenlidir. with biçimi daha kısadır ve otomatik uygulanır. Yalnızca standart kütüphanenin zaten bir context manager'a sarmadığı bir şey yapıyorken finally'e uzan.

Ne Zaman Yakalamamalı

Bir istisnayı yakalamak bir karardır — "bunu ele alabilirim" diyorsun. Edemiyorsan, istisnanın yayılmasına izin ver. Bunun gibi kod neredeyse her zaman bir hatadır:

try:
    do_work()
except Exception:
    pass  # her şeyi sessizce yok say

Hataları susturmak, bug'ları görünmez yapar. Tutarsız bir durumda topallamaktansa yüksek sesle çökmek daha iyidir.

Toparlama

  • try/except, toparlanabildiğin hataları ele almanı sağlar.
  • Körlemesine Exception değil, belirli istisnaları yakala.
  • raise, kendi kodunda hatayı işaret eder.
  • with blokları çoğu finally temizliğinin yerine geçer.
  • Şüphede kaldığında istisnanın yayılmasına izin ver.

Sırada: Python'un en sık fırlattığı belirli hataların turu — KeyError, ValueError, ModuleNotFoundError ve birkaç tane daha — artı onları hızlıca düzelten hata ayıklama alışkanlıkları.

Sıkça Sorulan Sorular

Python'da hataları nasıl ele alırım?

Riskli kodu bir try bloğuna sar ve belirli istisnayı bir except bloğunda yakala: try: risky() except ValueError: .... Opsiyonel else, istisna olmadıysa çalışır; finally temizlik için her iki durumda da çalışır.

Güvende olmak için Exception'ı yakalamalı mıyım?

Hayır. Çıplak bir except: veya except Exception:, öngörmediğin hataları gizler. Nasıl toparlayacağını bildiğin belirli istisnayı yakala ve geri kalanını yayılmaya bırak; böylece asıl sorunu görürsün.

raise ile raise from arasındaki fark nedir?

raise NewError(...) yeni bir istisna fırlatır. raise NewError(...) from original, orijinal istisnayı sebep olarak ekli tutar; Python bunu traceback'te gösterir. Daha düşük seviyeli bir hata, yüzeye çıkarmak istediğin daha üst seviyeli birini tetiklediğinde from kullan.

Coddy ile kodlamayı öğren

BAŞLA