6. İstisnalar
Şimdi istisnalara geçelim.
![]() |
İlk komut dosyası, istisnaların yönetilmesinin gerekliliğini göstermektedir.
# -*- coding=utf-8 -*-
# bir hata oluşturulur
x=4/0
Yorumlayıcı tarafından üretilen bilgileri görmek için kasıtlı olarak bir hata oluşturuyoruz. Ekran çıktısı şu şekildedir:
-
satırda şunlar yer almaktadır:
-
istisnanın türü: ZeroDivisionError;
- ilgili hata mesajı: integer division or modulo by zero. Mesaj İngilizce'dir. Bu, değiştirilmek istenebilecek bir durumdur.
Programlamada temel kural, yukarıdaki gibi "kontrolsüz" çökmeleri önlemek için her şeyi yapmamız gerektiğidir. Hata durumunda bile, program meydana gelen hata hakkında bilgi vererek düzgün bir şekilde sonlanmalıdır.
İstisna işleme sözdizimi şu şekildedir:
try:
actions susceptibles de lancer une exception
except [classe d'exception, ...]:
actions de gestion de l'exception
finally:
actions toujours exécutées qu'il y ait exception ou non
Try bloğunda, bir istisna oluştuğu anda işlemlerin yürütülmesi durur. Bu durumda, yürütme except bloğundaki işlemlerle devam eder.
except bloğu
except [MyException, ...]:
MyException türündeki veya bunun türevleri olan istisnaları yakalar. Bir try bloğunda bir istisna oluştuğunda, yorumlayıcı, try bloğuyla ilişkili except cümlelerini yazıldıkları sırayla inceler. Oluşan istisnayı işleyebilecek ilk except cümlesinde durur. Böyle bir cümle bulamazsa, istisna çağıran yönteme iletilir. Çağıran yöntemde bir try/except bloğu varsa istisna burada işlenir; aksi takdirde çağrılan yöntemler zinciri boyunca yukarı doğru iletilmeye devam eder. Son çare olarak, istisna Python yorumlayıcısına ulaşır. Yorumlayıcı, bu durumda yürütülen programı durdurur ve önceki örnekte gösterilen türde bir hata mesajı görüntüler. Dolayısıyla kural şudur: ana program, çağrılan yöntemlerden yukarı doğru iletilebilecek tüm istisnaları yakalamalıdır.
Bir istisna, meydana gelen hata hakkında bilgileri de beraberinde taşır. Bu bilgilere aşağıdaki sözdizimiyle ulaşılabilir:
except MyException as informations:
bilgiler, istisna ile ilgili bilgileri içeren bir tuple'dır.
Sözdizimi
except MyException, erreur:
sözdizimi, istisna ile ilgili hata mesajını erreur değişkenine atar.
Bir istisna oluşturmak için şu sözdizimi kullanılır:
raise MyException(param1, param2, ...)
kullanılır; burada MyException genellikle Exception sınıfından türetilmiş bir sınıftır. Sınıfın oluşturucusuna aktarılan parametreler, istisna yakalama yapılarının except cümlesinde kullanılabilir olacaktır.
Bu kavramlar aşağıdaki komut dosyasında gösterilmiştir.
Aşağıdaki komut dosyası hataları açıkça yönetir:
# -*- coding=utf-8 -*-
i=0
# bir hata oluşturuluyor ve yönetiliyor
x=2
try:
x=4/0
except ZeroDivisionError, erreur:
print ("%s : %s ") % (i, erreur)
# x'in değeri değişmedi
print "x=%s" % (x)
# yeniden başlıyoruz
i+=1
try:
x=4/0
except Exception, erreur:
# en genel istisnayı yakalıyoruz
print ("%s : %s ") % (i, erreur)
# birden fazla istisna türü yakalanabilir
i+=1
try:
x=4/0
except ValueError, erreur:
# bu istisna burada gerçekleşmiyor
print ("%s : %s ") % (i, erreur)
except Exception, erreur:
# en genel istisnayı yakalıyoruz
print ("%s : (Exception) %s ") % (i, erreur)
except ZeroDivisionError, erreur:
# belirli bir tür yakalanır
print ("%s : (ZeroDivisionError) %s ") % (i, erreur)
# sırayı değiştirerek yeniden deniyoruz
i+=1
try:
x=4/0
except ValueError, erreur:
# bu istisna burada gerçekleşmiyor
print ("%s : %s ") % (i, erreur)
except ZeroDivisionError, erreur:
# belirli bir tür yakalanıyor
print ("%s : (ZeroDivisionError) %s ") % (i, erreur)
except Exception, erreur:
# en genel istisna yakalanıyor
print ("%s : (Exception) %s ") % (i, erreur)
# argüman içermeyen bir except cümlesi
i+=1
try:
x=4/0
except:
# istisnanın türü veya hata mesajı dikkate alınmıyor
print ("%s : il y a eu un probleme ") % (i)
# başka bir istisna türü
i+=1
try:
x=int("x")
except ValueError, erreur:
print ("%s : %s ") % (i, erreur)
# bir istisna, programa erişilebilir bir tuple içinde bilgi taşır
i+=1
try:
x=int("x")
except ValueError as infos:
print ("%s : %s ") % (i, infos)
# istisnalar atılabilir
i+=1
try:
raise ValueError("param1","param2","param3")
except ValueError as infos:
print ("%s : %s ") % (i, infos)
# Kendi istisnalarınızı oluşturabilirsiniz
class MyError(Exception):
pass
# MyError istisnası tetiklenir
i+=1
try:
raise MyError("info1","info2", "info3")
except MyError as infos:
print ("%s : %s ") % (i, infos)
# MyError istisnası atılır
i+=1
try:
raise MyError("mon msg d'erreur")
except MyError, erreur:
print ("%s : %s ") % (i, erreur)
# herhangi bir nesne türü atılabilir
class Objet:
def __init__(self,msg):
self.msg=msg
def __str__(self):
return self.msg
i+=1
try:
raise Objet("pb...")
except Objet as erreur:
print "%s : %s" % (i, erreur)
# finally bloğu her zaman yürütülür
# istisna olsun ya da olmasın
i+=1
x=None
try:
x=1
except:
print "%s : exception" % (i)
finally:
print "%s : finally x=%s" % (i,x)
i+=1
x=None
try:
x=2/0
except:
print "%s : exception" % (i)
finally:
print "%s : finally x=%s" % (i,x)
Notlar:
- 6-9. satırlar: sıfıra bölme hatası işlenir;
-
- satır: Oluşan istisnayı yakalıyoruz;
-
- satır: Oluşan istisna nedeniyle, x bir değer almamıştır ve dolayısıyla değeri değişmemiştir;
- 15-19. satırlar: Aynı işlem tekrarlanır, ancak bu sefer Exception türünde daha üst düzey bir istisna yakalanır. ZeroDivisionError istisnası, Exception sınıfından türediği için, except cümlesi bunu durduracaktır;
- 23-33. satırlar: Birden fazla istisna türünü yönetmek için birden fazla except cümlesi eklenir. İstisna hiçbir except cümlesini karşılamıyorsa, tek bir except cümlesi yürütülür veya hiç yürütülmez;
- satır 51-55: except cümlesi hiçbir argüman içermeyebilir. Bu durumda, tüm istisnaları durdurur;
- satır 59-62: ValueError istisnasını başlatır;
- 66-69. satırlar: istisna tarafından taşınan bilgiler alınır;
- 73-76. satırlar: bir istisna oluşturma yöntemini gösterir;
- 79-84. satırlar: özel bir istisna sınıfı olan MyError'in kullanımını gösterir;
- 79-80. satırlar: MyError sınıfı, yalnızca temel sınıf olan Exception'ten türetilmiştir. Temel sınıfına hiçbir şey eklemez. Ancak artık except cümlelerinde açıkça adlandırılabilir;
- 97-107. satırlar: Python'da aslında sadece Exception sınıfından türetilen nesneler değil, herhangi bir nesne türünün atılabileceğini göstermektedir;
- 109-127. satırlar: finally cümlesinin kullanımını göstermektedir.
Ekran çıktısı şu şekildedir:
0 : integer division or modulo by zero
x=2
1 : integer division or modulo by zero
2 : (Exception) integer division or modulo by zero
3 : (ZeroDivisionError) integer division or modulo by zero
4 : il y a eu un probleme
5 : invalid literal for int() with base 10: 'x'
6 : invalid literal for int() with base 10: 'x'
7 : ('param1', 'param2', 'param3')
8 : ('info1', 'info2', 'info3')
9 : mon msg d'erreur
10 : pb...
11 : finally x=1
12 : exception
12 : finally x=None
Bu yeni komut dosyası, istisnaların çağıran yöntemler zincirinde yukarı doğru iletilmesini göstermektedir:
# -*- coding=utf-8 -*-
# özel bir istisna
class MyError(Exception):
pass
# üç yöntem
def f1(x):
# istisnalar yönetilmez - otomatik olarak üst katmana iletilir
return f2(x)
def f2(y):
# istisnalar yönetilmez - otomatik olarak üst katmana iletilir
return f3(y)
def f3(z):
if (z % 2) == 0:
# z çift ise, bir istisna atılır
raise MyError("exception dans f3")
else:
return 2*z
#---------- main
# istisnalar, çağrılan yöntemler zinciri boyunca yukarı doğru iletilir
# bir yöntem tarafından yakalanana kadar. Burada bu yöntem main olacaktır
try:
print f1(4)
except MyError as infos:
print "type :%s, arguments : %s" % (type(infos),infos)
# Bir yöntem, ilettiği istisnaları zenginleştirebilir
def f4(x):
try:
return f5(x)
except MyError as infos:
# istisna zenginleştirilir ve ardından yeniden atılır
raise MyError(infos,"exception dans f4")
def f5(y):
try:
return f6(y)
except MyError as infos:
# istisnayı zenginleştirip yeniden atıyoruz
raise MyError(infos, "exception dans f5")
def f6(z):
if (z % 2) == 0:
# bir istisna atılır
raise MyError("exception dans f6")
else:
return 2*z
#---------- main
try:
print f4(4)
except MyError as infos:
print "type :%s, arguments : %s" % (type(infos),infos)
Notlar:
- 27-30. satırlarda, main --> f1 --> f2 --> f3 çağrısında (28. satır), f3 tarafından tetiklenen MyError istisnası, main'e kadar yayılacaktır. Bu istisna daha sonra 29. satırdaki except maddesi tarafından işlenecektir;
- 55-58. satırlar: main --> f4 --> f5 --> f6 çağrısında (56. satır), f6 tarafından tetiklenen MyError istisnası, main'e kadar geriye doğru izlenecektir. Ardından, 29. satırdaki except maddesi tarafından işlenecektir. Bu sefer, çağıran yöntemler zincirinde yukarı doğru ilerlerken, MyError istisnası, yukarı doğru ilerleyen her yöntem tarafından eklenen bilgilerle zenginleştirilir.
Ekran çıktısı şu şekildedir:
