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
try:riskli kodun bloğunu açar.except ValueError:, o belirli istisnatryiçinde fırlatılırsa onu yakalar.- Hiçbir istisna tetiklenmezse
excepttamamen 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:
Bir tuple geçerek tek bir cümlede birden fazla istisnayı yakalayabilirsin:
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,trybloğu istisna fırlatmadan bittiyse çalışır.finally, istisna olsa da olmasa da çalışır.
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:
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:
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:
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
Exceptiondeğil, belirli istisnaları yakala. raise, kendi kodunda hatayı işaret eder.withblokları çoğufinallytemizliğ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.