8. Hata Ayıklama#
Python’da hatalı bir işlem yaptığımız, örneğin tanımlanmamış bir değişkeni kullanmaya çalıştığımızda, bir fonksiyona hatalı veri tipinde argüman girdiğimizde, hatanın nerden kaynaklandığını belirten mesajlarla karşılaşırız. Örneğin daha önce tanımlanmamış olan bir x değişkenini kullanmaya çalıştığımızda aşağıdaki gibi bir mesajla karşılaşırız.
print(x)
----------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-2-81745ac23551> in <module>()
----> 1 print(x)
NameError: name 'x' is not defined
Hata mesajındaki son satır, hatanın neden kaynaklandığını belirtmektedir. Buradaki mesaj, (NameError: İsim Hatası) ‘x’ değişkeninin tanımlanmamış olduğunu söylüyor. Aynı şekilde herhangi bir pakette yer alan fonksiyonu, paketi ya da ilgili fonksiyonu içeri aktarmaksızın kullanmaya kalkarsak da aynı mesajla karşılaşırız.
reduce(lambda x1,x2: x1 + x2, [3, 5, 7, 9])
NameError: name 'reduce' is not defined
Ya da program çalışırken sir sayıyı sıfırla bölmeye çalışırsak buna ilişkin bir hata mesajıyla karşılaşırız ve programın çalışması durur. ZeroDivisionError, sıfırla bölme hatası anlamına geliyor.
5 / 0
ZeroDivisionError: division by zero
Şimdi de sayısal bir değer kullanmamız gereken yerde metin tipinde bir değişken kullanalım. Görüldüğü gibi sayısal değer kullanmamız gereken bir fonksiyonda str (metin) tipinde veri kullandığımız için TypeError (Tür Hatası) ile karşılaşıyoruz.
us = 'iki'
5 ** us
TypeError: unsupported operand type(s) for ** or pow(): 'int' and 'str'
Son bir örnek olarak bilinmeyen bir paketi içeri aktarmaya çalışalım. Burada da ModuleNotFound
yani modül bulunamadı hatası ile karşılaşıyoruz.
import yeni_paket
ModuleNotFoundError: No module named 'yeni_paket'
Yukarıda örneklerini gördüğümüz, NameError, ZeroDivisionError, ModuleNotFoundError gibi mesajlara istisna (exeption) denir. Python’da yer karşılaşılabilecek hatalar için geliştirilmiş çok sayıda istisna mesajı vardır. Bunların https://docs.python.org/3/library/exceptions.html adresinden ulaşılabilir.
Biz de yazdığımız programlarda kullanıcı hatalarına karşı uygun istisna mesajları yazarak olası hataların önüne geçebiliriz. Python’da hata yakalamanın bir yolu try – except
anahtar kelimelerini kullanmaktır. Try
kelimesinden sonra, çalıştırılmak istenen kod, except
kelimesinden sonra da bu kod çalışmazsa verilecek mesaj yer alır. Örnek olarak verilen değerin karekökünü bulan bir fonksiyon yazalım.
def karekok(girdi):
try:
return girdi ** 0.5
except:
print('Argüman sayısal bir değer olmalı!!!')
print(karekok(16))
4.0
print(karekok('dort'))
Argüman sayısal bir değer olmalı!!!
None
Tanımladığımız fonksiyon önce verilen değerin karekökünü bulmayı deniyor (2. ve 3. satırlar). Burada bir hata ile karşılaşırsa except
anahtar kelimesi ile gösterilen kısma geçiyor ve belirtilen hata mesajını veriyor.
Örnek olarak basit bir başka fonksiyona bakalım. Şimdi de bir bölme fonksiyonu yazalım. Tabii ki böyle bir fonksiyona hiçbir zaman ihtiyacımız olmayacak ama try, except
yapısının nasıl çalıştığını görmek için bu fonksiyonu kullanabiliriz.
def bolme(x,y):
try:
return x / y
except:
print("Sıfırla bölme hatası")
print(bolme(10, 4))
2.5
print(bolme(5, 0))
Sıfırla bölme hatası
None
Beklediğimiz gibi bölen sıfır olduğunda program istediğimiz hatayı veriyor ve None değerini döndürüyor.
Son olarak metin girilmesi gerektiği halde girilmeyen bir fonksiyon için try – except
yapısı kuralım.
def tekrar_et(kelime, sayi):
try:
print("Sonuc: " + kelime * sayi)
except:
print("Argüman olarak bir metin ve bir tamsayı girin!!!")
print(tekrar_et("deneme ", 3))
Sonuc: deneme deneme deneme
None
print(tekrar_et(5, 3))
Argüman olarak bir metin ve bir tamsayı girin!!!
None
İstersek türünü bildiğimiz hatalardan biri veya daha fazlası ile karşılaşıldığında da belirli bir hata mesajı verilmesini sağlayabiliriz. Yukarıdaki karekök alma örneğinde sayısal bir değer yerine metin tipindeki verinin girilmesinin TypeError
olduğunu biliyoruz. Bu nedenle programa TypeError
ile karşılaştığında nasıl bir mesaj vermesi gerektiğini söyleyebiliriz.
def karekok(girdi):
try:
return girdi ** 0.5
except TypeError:
print('Argüman sayısal bir değer olmalı!!!')
print(karekok("yirmi"))
Argüman sayısal bir değer olmalı!!!
None
Yazdığımız kodun belirli durumlarda hata ya da uyarı mesajı vermesini de isteyebiliriz. Yukarıda verdiğimiz karekök bulma örneğinde eğer eksi bir sayı girilirse normalde program karmaşık bir sayı üretecektir.
print(karekok(-16))
(2.4492935982947064e-16+4j)
Ancak, eksi bir sayı girildiğinde uyarı mesajı verilmesini istiyor olalım.
def karekok(girdi):
if girdi < 0:
raise ValueError("Eksi bir sayı girdiniz!!!")
try:
return girdi ** 0.5
except TypeError:
print('Argüman sayısal bir değer olmalı!!!')
print(karekok(-16))
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[15], line 1
----> 1 print(karekok(-16))
Cell In[14], line 3, in karekok(girdi)
1 def karekok(girdi):
2 if girdi < 0:
----> 3 raise ValueError("Eksi bir sayı girdiniz!!!")
4 try:
5 return girdi ** 0.5
ValueError: Eksi bir sayı girdiniz!!!
def tekrar_et(kelime, sayi):
if sayi < 0:
raise ValueError("Sayı sıfırdan küçük olamaz!!!")
try:
print("Sonuc: " + kelime * sayi)
except:
print("Argüman olarak bir metin ve bir tamsayı girin!!!")
print(tekrar_et("deneme", -3))
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[19], line 1
----> 1 print(tekrar_et("deneme", -3))
Cell In[18], line 3, in tekrar_et(kelime, sayi)
1 def tekrar_et(kelime, sayi):
2 if sayi < 0:
----> 3 raise ValueError("Sayı sıfırdan küçük olamaz!!!")
4 try:
5 print("Sonuc: " + kelime * sayi)
ValueError: Sayı sıfırdan küçük olamaz!!!