Python Programlama Dili 8. Hata Yakalama Hatalar programcılık deneyiminizin bir parçasıdır. Ancak bizim burada kastettiğimiz, programınızı çalıştıran kullanıcıların sebep olduğu ve programınızın çökmesine yol açan kusurlar. Dilerseniz şöyle bir örnek verelim: print "Girdiğiniz sayı", sayi print "Teşekkürler. Hoşçakalın!" Bu program görünüşte herhangi bir kusur taşımıyor. Eğer kullanıcımız burada bizim istediğimiz gibi bir sayı girerse bu programda hiçbir sorun çıkmaz. Peki ama ya kullanıcı sayı yerine harf girerse ne olacak? Böyle bir durumda programımız şöyle bir hata mesajı verir: Gördüğünüz gibi, ortaya çıkan hata nedeniyle programın son satırı ekrana basılamadı. Yani programımız hata yüzünden çöktüğü için işlem yarıda kaldı. Burada böyle bir hata almamızın nedeni, kullanıcıdan sayı beklediğimiz halde kullanıcının harf girmesidir. Biz yukarıdaki programda int() fonksiyonunu kullanarak kullanıcıdan aldığımız karakter dizilerini sayıya dönüştürmeye çalışıyoruz. Yukarıdaki kodun, çok uzun bir programın parçası olduğunu düşünürsek, kullanıcının yanlış veri girişi programın çökmesine veya durmasına yol açabilir. Bu tür durumlarda
Python gerekli hata mesajını ekrana yazdırarak kullanıcıyı uyaracaktır, ama tabii ki Python un sunduğu karmaşık hata mesajlarını kullanıcının anlamasını bekleyemeyiz. Böylesi durumlar için Python da try... except ifadeleri kullanılır. 8.1. try... except... Giriş bölümünde verdiğimiz örneği hatırlıyorsunuz. Şimdi hata mesajına tekrar bakalım: Burada önemli kısım ValueError dur. Hatayı yakalarken bu ifade işimize yarayacak. Python da hata yakalama işlemleri iki adımdan oluşur. Önce ne tür bir hata ortaya çıkabileceği tespit edilir. Daha sonra bu hata meydana geldiğinde ne yapılacağına karar verilir. Buna göre, kullanıcı sayı yerine harf girerse ValueError denen bir hata meydana geliyor. Şimdi de böyle bir hata ortaya çıkarsa ne yapacağımıza karar vermemiz gerekiyor. Mesela öyle bir durumda kullanıcıya, Lütfen harf değil, sayı girin! gibi bir uyarı mesajı gösterebiliriz. Dilerseniz bu dediklerimizi somutlaştıralım: #!/usr/bin/env python # -*- coding: utf-8 -*- print "Girdiğiniz sayı", sayi except ValueError: print "Lütfen harf değil, sayı girin!" print "Teşekkürler. Hoşçakalın!" Burada, hata vereceğini bildiğimiz kodları bir try... bloğu içine aldık. Ardından bir except bloğu açarak, ne tür bir hata beklediğimizi belirttik. Buna göre, beklediğimiz hata türü ValueError. Son olarak da hata durumunda kullanıcıya göstereceğimiz mesajı yazdık. Artık kullanıcılarımız sayı yerine harfe basarsa programımız çökmeyecek, aksine çalışmaya devam edecektir. Dikkat ederseniz print Teşekkürler. Hoşçakalın! satırı her koşulda ekrana basılıyor. Yani kullanıcı doğru olarak sayı da girse, yanlışlıkla sayı
yerine harf de girse programınız yapması gereken işlemleri tamamlayıp yoluna devam edebiliyor. Konuyu daha iyi anlayabilmek için bir örnek daha verelim. Şimdi şöyle bir program yazdığımızı düşünün: Eğer burada kullanıcı ikinci sayıya 0 cevabı verirse programımız şöyle bir hata mesajı verip çökecektir. Çünkü bir sayı 0 a bölünemez: File "deneme.py", line 7, in <module> ZeroDivisionError: float division Böyle bir durumda hata alacağımızı bildiğimize göre ilk adım olarak ne tür bir hata mesajı alabileceğimizi tespit ediyoruz. Buna göre alacağımız hatanın türü ZeroDivisionError. Şimdi de böyle bir hata durumunda ne yapacağımıza karar vermemiz gerekiyor. İsterseniz yine kullanıcıya bir uyarı mesajı gösterelim. Kodlarımızı yazıyoruz: except ZeroDivisionError: print "Lütfen sayıyı 0'a bölmeye çalışmayın!" Burada önemli bir problem dikkatinizi çekmiş olmalı. Biz yukarıdaki kodlarda, kullanıcının bir sayıyı 0 a bölmesi ihtimaline karşı ZeroDivisionError hatasını yakaladık.
Ama ya kullanıcı sayı yerine harf girerse ne olacak? ZeroDivisionError ile birlikte ValueError u da yakalamamız gerekiyor... Eğer yukarıdaki kodları çalıştıran bir kullanıcı sayı yerine harf girerse şöyle bir hatayla karşılaşır: Buradan anladığımıza göre hata veren satır şu: ilk = int(raw_input("bölme işlemi için ilk sayıyı girin: ") Dolayısıyla bu satırı da try... bloğu içine almamız gerekiyor. Şu kodları dikkatlice inceleyin: except ZeroDivisionError: print "Lütfen sayıyı 0'a bölmeye çalışmayın!" except ValueError: print "Lütfen harf değil, sayı girin!" Gördüğünüz gibi hata vereceğini bildiğimiz kodların hepsini bir try... bloğu içine aldık. Ardından da verilecek hataları birer except bloğu içinde teker teker yakaladık. Eğer her iki hata için de aynı mesajı göstermek isterseniz şöyle bir şey yazabilirsiniz: except (ZeroDivisionError, ValueError): print "Girdiğiniz veri hatalı!"
Hata türlerini nasıl grupladığımıza dikkat edin. Hataları birbirinden virgülle ayırıp parantez içine alıyoruz... Böylece programımız her iki hata türü için de aynı uyarıyı gösterecektir. 8.2. pass Deyimi Bir hata ile karşılaşan programınızın hiçbir şey yapmadan yoluna devam etmesini isterseniz bu deyimi kullanabilirsiniz: except (ZeroDivisionError, ValueError): pass Böylece programınız ZeroDivisionError veya ValueError ile karşılaştığında sessizce yoluna devam edecek, böylece kullanıcımız programda ters giden bir şeyler olduğunu dahi anlamayacaktır. Eğer bir hatanın kullanıcıya gösterilmesinin gerekmediğini düşünüyorsanız yukarıdaki kodları kullanın, ama eğer verilen hata önemli bir hataysa ve kullanıcının bu durumdan haberdar olması gerektiğini düşünüyorsanız, bu hatayı pass ile geçiştirmek yerine, kullanıcıya hatayla ilgili makul ve anlaşılır bir mesaj göstermeyi düşünebilirsiniz.