Python'da try, except, else ve finally dört ayrı iş yapar. try hata çıkarabilecek kodu dener, except yakalanan hatayı ele alır, else yalnızca try hatasız bittiğinde çalışır, finally ise hata olsa da olmasa da çalışan temizlik adımıdır. Bu yazıda ilk ikisini kısa kodlarla deneyeceksin; finally ve karar tablosu sonraki bölümlerde.
try ve except: Hatayı Belirli Türle Yakalamak
try içine hata çıkabilecek tek bir iş yaz, except ile de o işin vereceği hata türünü yakala. Python'da int("abc") gibi sayıya çevrilemeyen bir metin ValueError fırlatır. Bu hata yakalanmazsa program çöker; yakalanırsa akış except bloğuna geçer.
try:
sayi = int("abc")
print("Sayı:", sayi)
except ValueError:
print("Geçerli bir tam sayı girmedin.")
Beklenen çıktı:
Geçerli bir tam sayı girmedin.
İlk satırdaki dönüştürme hata verdiği için print("Sayı:", sayi) hiç çalışmaz. Hata türü ValueError olduğundan except devreye girer.
Birden fazla except: sıra önemlidir
Python except bloklarını yukarıdan aşağıya sırayla dener ve hatayla uyuşan ilk blokta durur; kalanlara bakmaz. Bu yüzden özel türler üstte, geniş tür olan Exception en altta durmalıdır.
def bol(a, b):
try:
return int(a) / int(b)
except ValueError:
print("Sayı girmelisin.")
except ZeroDivisionError:
print("Sıfıra bölemezsin.")
except Exception as hata:
print("Beklenmeyen hata:", hata)
print(bol("10", "abc"))
print(bol("10", "0"))
print(bol("10", "2"))
Beklenen çıktı:
Sayı girmelisin.
None
Sıfıra bölemezsin.
None
5.0
Hata yakalanan çağrılarda fonksiyon return satırına ulaşamadığı için None döner. Exception bloğunu en üste yazsaydın her hata ona takılırdı ve alttaki özel bloklar hiç çalışmazdı. Geniş yakalamayı yalnızca son çare olarak tut ve hatayı en azından yazdır ya da kaydet; sessizce yutmak, hatanın nedenini bulmayı zorlaştırır.
else Bloğu Ne Zaman Çalışır?

else yalnızca try bloğu hiç hata vermeden bittiğinde çalışır. Hata çıkarsa else atlanır ve ilgili except devreye girer. Önemli ayrıntı şu: else içinde çıkan bir hata, aynı try'ın except bloklarına takılmaz; yakalanmadan yukarı çıkar.
Bu yüzden iyi bir kural vardır: yalnızca hata verebilecek satır try'da, başarılı olduktan sonra yapılacak işler else'te durur. Farkı bir örnekle görelim. Önce her şeyi try içine yazan sürüm:
import math
def kok_a(metin):
try:
sayi = int(metin)
print("Kök:", math.sqrt(sayi))
except ValueError:
print("Geçersiz sayı.")
kok_a("-4")
Beklenen çıktı:
Geçersiz sayı.
"-4" geçerli bir tam sayıdır; asıl hatayı math.sqrt verir, o da ValueError türündedir. Except bu hatayı yanlışlıkla yakalar ve mesaj yanıltıcı olur. Şimdi else kullanan sürüm:
def kok_b(metin):
try:
sayi = int(metin)
except ValueError:
print("Geçersiz sayı.")
else:
print("Kök:", math.sqrt(sayi))
kok_b("16")
kok_b("abc")
kok_b("-4")
Beklenen çıktı:
Kök: 4.0
Geçersiz sayı.
Traceback (most recent call last):
...
ValueError: ...
Önce "16" için dönüştürme başarılı olur ve else çalışır. "abc" için except devreye girer, else atlanır. "-4" için dönüştürme başarılıdır, ancak else içindeki math.sqrt hata verir ve bu hata except'e takılmadan görünür olur. Hata mesajının ayrıntısı Python sürümüne göre değişebilir; önemli olan hatanın gizlenmemesidir.
finally ve return: Temizlik Adımı Akışı Nasıl Etkiler?
finally bloğu hata çıksa da çıkmasa da çalışır. try ya da except içinde return olsa bile fonksiyon geri dönmeden hemen önce finally çalıştırılır.
def deneme():
try:
print("try çalıştı")
return "try'dan dönen değer"
finally:
print("finally çalıştı")
print(deneme())
Beklenen çıktı:
try çalıştı
finally çalıştı
try'dan dönen değer
Önce try içindeki print çalışır. return satırına gelince dönecek değer hazırlanır, ama fonksiyon henüz bitmez; Python önce finally bloğunu çalıştırır. Dışarıdaki print değeri en son görür, bu yüzden değer çıktının son satırında görünür.
finally içine return yazma tuzağı
Python dokümantasyonuna göre finally bloğu bir return çalıştırırsa bekleyen istisna iptal edilir. Hata sessizce kaybolur.
def tuzak():
try:
raise ValueError("Bir sorun var")
finally:
return "finally döndü"
print(tuzak())
Beklenen çıktı:
finally döndü
raise bir ValueError başlatır, ama finally içindeki return o hatayı iptal eder. Program çökmez, hata mesajı da görünmez. Bu yüzden finally yalnızca temizlik için kullanılır: dosya kapatmak, bağlantıyı bırakmak gibi.
Aynı Fonksiyonla Üç Akış: Hatalı Giriş, Başarılı Giriş ve Kaynak Kapatma

Dört bloğu tek fonksiyonda görelim:
def sayiya_cevir(metin):
try:
sayi = int(metin)
except ValueError:
print("Hata: sayıya çevrilemedi")
return None
else:
print("Başarılı: çevrildi")
return sayi
finally:
print("Çeviri denemesi bitti")
print(sayiya_cevir("abc"))
print(sayiya_cevir("42"))
Beklenen çıktı:
Hata: sayıya çevrilemedi
Çeviri denemesi bitti
None
Başarılı: çevrildi
Çeviri denemesi bitti
42
Akış 1 ("abc"): int("abc") ValueError üretir. except hata mesajını yazar. else atlanır, çünkü yalnızca hata çıkmazsa çalışır. finally mesajı yazılır ve None döner.
Akış 2 ("42"): Çevirme başarılıdır, except atlanır. else başarı mesajını yazar, finally kendi mesajını yazar, 42 en son döner.
Akış 3: dosyayı finally ile kapatmak
def ilk_satiri_oku(yol):
dosya = None
try:
dosya = open(yol, encoding="utf-8")
return dosya.readline()
except FileNotFoundError:
print("Dosya bulunamadı")
return ""
finally:
if dosya is not None:
dosya.close()
print("Dosya kapatıldı")
print(ilk_satiri_oku("yok.txt"))
Beklenen çıktı ("yok.txt" diye bir dosya yoksa; son satır, boş metnin yazdırdığı boş satırdır):
Dosya bulunamadı
open() dosyayı bulamazsa FileNotFoundError verir ve dosya değişkenine hiçbir şey atanmaz. Bu yüzden değişkene baştan None veriyoruz. finally içinde None olup olmadığına bakmasaydık, olmayan bir dosyayı kapatmaya çalışıp yeni bir hata alırdık. Dosya varsa önce "Dosya kapatıldı" yazılır, ardından okunan satır ekrana gelir.
Aynı işi with ifadesi çok daha kısa yapar: with open(yol, encoding="utf-8") as dosya: yazdığında dosya, bloktan çıkınca hata olsa bile otomatik kapanır. Elle finally yazmanın kısa karşılığıdır; yine de dosyanın bulunamaması gibi hataları except ile yakalaman gerekir.
Hata yönetimini küçük alıştırmalarla pekiştirmek istersen birebir Python dersleri kapsamında bu yapıları kişiye özel ödevlerle çalışabilirsin.
Hangi Durumda Hangi Blok Çalışır? Karar Tablosu
Aşağıdaki tabloda her bloğun içinde birer print satırı olduğunu varsay. Tablo, hangi durumda hangi blokların çalıştığını ve ekrana ne çıktığını gösterir.
| Durum | Çalışan bloklar | Ekrana çıkan sonuç |
|---|---|---|
| Hata yok | try, else, finally | try, else ve finally çıktıları sırayla görünür; program devam eder. |
| Eşleşen hata var | try'ın hata öncesi kısmı, except, finally | Hatadan önceki try çıktısı, except mesajı ve finally çıktısı görünür; program devam eder. |
| Eşleşmeyen hata var | try'ın hata öncesi kısmı, finally | Hatadan önceki try çıktısı ve finally çıktısı görünür; ardından hata yukarı çıkar, yakalayan yoksa hata mesajı (traceback) yazılır ve program durur. |
| else içinde hata var | try, else'in hata öncesi kısmı, finally | try çıktısı, hatadan önceki else çıktısı ve finally çıktısı görünür; hata aynı try'ın except bloklarınca yakalanmadan çıkar. |
| try içinde return var | try, finally | try ve finally çıktıları görünür, ardından değer döner; else çalışmaz. |
Tabloyu okurken önce finally sütununa bak: her satırda yer alır. except ile else ise aynı çalıştırmada birlikte görünmez; biri hata olduğunda, diğeri hata olmadığında devreye girer.
try-except Yazarken Sık Yapılan Hatalar
- Gereğinden geniş
except Exceptionkullanmak: Her hatayı aynı kovaya atar ve hatanın gerçekte hangi türde olduğunu görmeni engeller. Beklediğin türü yaz (ValueError,ZeroDivisionErrorgibi). Geniş yakalama gerekiyorsa mesajı yazdır ya da kayda al. - Çıplak
exceptya daexceptiçindepassyazmak: Hatayı sessizce geçer, program yanlış çalışsa bile iz kalmaz. Python dokümantasyonuna göreException,BaseExceptionsınıfının altındadır;KeyboardInterruptveSystemExitiseExceptionkapsamında değildir. Çıplakexceptbunları da yakalar, bu yüzden Ctrl+C ile programı durdurmak bile zorlaşabilir. Hatayı susturma; mesajı yazdır, kayda al ya daraiseile yeniden fırlat. tryiçine çok fazla satır koymak: Hatanın hangi satırdan geldiği belirsizleşir ve ilgisiz bir hata yanlışexcepttarafından yakalanabilir. Yalnızca hata çıkarabilecek satırıtryiçine al; devamınıelsebloğuna taşı.- Özel
except'i geniş olanın arkasına yazmak: Python bloğu yukarıdan aşağı tarar ve ilk eşleşeni çalıştırır.except Exceptionönce gelirse ondan sonrakiexcept ValueErrorhiç çalışmaz. Önce özel türleri, en sonda gerekirse geniş olanı yaz. finallyiçindereturnkullanmak: Bureturn,tryiçindeki dönüş değerinin ve bekleyen hatanın yerine geçebilir; hata sessizce kaybolabilir.finallybloğunu yalnızca temizlik için kullan, değeri blok dışında döndür.finally'de kapatılacak nesneyi tanımlanmadan kullanmak:open()satırı hata verirse dosya değişkeni hiç oluşmaz vefinallyiçindekikapat()çağrısıNameErrorüretir. Değişkenitry'dan önceNoneile başlatıp kontrol et ya dawithifadesini kullan.else'i hiç kullanmamak ya da yanlış anlamak:else, hata olduğunda çalışan blok değildir;tryhatasız bittiğinde çalışır. Başarı durumuna ait kodutry'ın içine yığmak yerineelse'e yaz.
Bu maddeleri kendi kodunda ne kadar yakaladığını görmek istersen ücretsiz Python bilgi testini çözebilirsin. Testteki sorular hangi bilgiyi pekiştirmen gerektiğini fark etmene yardımcı olur.
Sık Sorulan Sorular
try except yazarken else bloğu zorunlu mu?
Hayır. else isteğe bağlıdır. Bir try bloğu için en az bir except ya da finally yeterlidir. else, yalnızca hata çıkmadığında çalışmasını istediğin kodu try'dan ayırmak istediğinde işe yarar.
finally bloğu her durumda çalışır mı?
Hata olsun olmasın, try içinde return bulunsun bulunmasın finally çalışır. Program işletim sistemi düzeyinde aniden sonlandırılırsa ya da süreç öldürülürse çalışma şansı kalmaz; gündelik kodda bu durumu düşünmen gerekmez.
except Exception ile belirli bir hata türünü yakalamak arasında ne fark var?
Belirli tür (örneğin ValueError) yalnızca beklediğin hatayı yakalar, diğer hatalar görünür kalır. except Exception neredeyse tüm hataları yakalar ve gerçek nedeni gizleyebilir. Önce belirli türleri yazmak, geniş yakalamayı yalnızca mesajı yazdırmak ya da kayda almak gibi bilinçli bir amaçla kullanmak daha sağlıklıdır.
else bloğundaki kodu try bloğuna yazsam ne değişir?
Kod aynı sırayla çalışır ama bu kodun içinde çıkan hata da aynı try'ın except bloğuna düşer. Yani beklemediğin bir hata, yanlışlıkla yakalanıp başka bir hatanın mesajıyla karışabilir. else'e yazdığında bu kodun hataları except tarafından yakalanmaz, böylece try yalnızca denediğin riskli satırı korur.
Özetle, try riskli satırı dener, except beklediğin hatayı karşılar, else başarı durumunu ayırır, finally temizliği garanti eder. Karar tablosunu küçük örneklerle kendi dosyanda çalıştırmak, hangi bloğun ne zaman devreye girdiğini en net biçimde gösterir.