Veri Bilimi İçin Python Notları-12: Python’da Hata Ayıklama Yöntemleri

V

1. Python’da Hata Ayıklama Yöntemlerinin Temel Kavramları

Daha önceki makalelerde zaman zaman kullanılan “try, except, else ve finally” gibi hata ayıklama blokları, kodlarda oluşan hataları yönetmemize olanak tanıyan yapılardır.

“try” ifadesi, hatanın oluşup oluşmayacağını test etmemizi sağlar.

“except” ifadesi, oluşan hatayı işlememizi sağlar. Örneğin hata oluşunca konsola “Hata oluştu.” yazdırılması gibi.

“else” ifadesi, herhangi bir hata oluşmadığı durumda çalışmasını istediğimiz kodları ekleyeceğimiz bölümdür.

“finally” ifadesi ise “try” ve “except” bloklarının sonuçlarından bağımsız olarak çalışmasını istediğimiz kodların yer alacağı kısımdır.

“try, except, else ve finally” bloklarını detaylı olarak incelemeden önce konunun ana hatlarını yansıtan ve daha önceki makalelerde de sık sık kullanılan aşağıdaki örneği inceleyebilirsiniz. “myList“ isimli liste tipi nesnenin kendisini silen aşağıdaki kodlar çalıştırıldığında print satırında bir hata alınacaktır.

myList = ["Volvo", 2006, "Volvo", 1.6, 2006, True]

#myList değişkenini tümüyle silmek; sadece elemanlarının tümünü değil kendisini de silmek.
myList = ["Volvo", 2006, "Volvo", 1.6, 2006, True]
del myList
print(myList) #Sonuç: NameError: name 'myList' is not defined

“myList” isimli nesnenin gerçekten silinip silinmediğini, kodların çalışmasında herhangi bir kesinti olmadan kontrol etmek istediğimizi varsayalım. Bunun için aşağıdaki kodları ve açıklamaları inceleyebilirsiniz.

myList = ["Volvo", 2006, "Volvo", 1.6, 2006, True]

#myList değişkenini tümüyle silmek; sadece elemanlarının tümünü değil kendisini de silmek.
myList = ["Volvo", 2006, "Volvo", 1.6, 2006, True]
del myList
#print(myList) #Sonuç: NameError: name 'myList' is not defined

#myList değişkeninin tümüyle silinip silinmediğinin kontrolü.
try: print(myList) #Hatanın oluşup oluşmayacağı test edildi.
except NameError: myList = None #Hata oluşursa myList, None olsun.
if myList is None: #Eğer myList, None ise koşul gerçekleşecek. 
    print("Mylist değişkeni artık yok.") #Sonuç: Mylist değişkeni artık yok.
else: #Eğer myList, None değil ise koşul gerçekleşmeyecek. 
    print("Mylist değişkeni var.")

2. Python’da Hatanın Varlığı Durumu (try, except blokları)

Python’da kodlar çalışırken herhangi bir hata oluştuğunda (yukarıda print metodunda oluşan hata gibi) normalde Python durur ve konsola bir hata mesajı yazdırır. Hata oluştuğunda Python’un durmaması ve hatayı işleyebilmek ya da ayıklayabilmek için “try” ve “except” bloklarını aşağıda gösterildiği gibi kullanabiliriz.

#try bloğu dışında print(x) kullanıldığında, öncesinde x değişkeni tanımlanmadığı için Python tanımlama hatası üretecektir.
#print(x) #Sonuç: NameError: name 'x' is not defined

# x değişkeni öncesinde tanımlanmadığı için try bloğu bir hata üretecektir; ancak Python hatadan dolayı durmayacaktır.
try:
    print(x)
except: #try bloğunda bir hata oluşması durumunda except bloğu çalışacağı için Python’un çalışmasında bir kesinti olmadan hatanın gerçekleşmiş olduğunu anlayacağız.
    print("Bir hata meydana geldi.") #Sonuç: Bir hata meydana geldi.

Yukarıdaki “except” bloğundan herhangi bir hatanın oluştuğunu anlayabiliriz. Ancak hatayı kaynağına göre ayrıştırarak işleyebilmek için aşağıda gösterildiği gibi hata kodu ile birlikte birden fazla “except” bloğu kullanabiliriz. Aşağıdaki örnekleri kodları çalıştırdıktan sonra incelemeniz önerilir.

# x değişken string bir değişken ile integer bir değişkenin toplamını temsil ettiği için TypeError kaynaklı bir hata örneği.
try:
    x = "ishakkutlu.com" + 2
except NameError: #eğer bu blok çalışırsa hatanın NameError kaynaklı olduğunu anlayacağız.
    print("NameError kaynaklı bir hata meydana geldi.") #Sonuç: NameError kaynaklı bir hata meydana geldi.   
except TypeError: #eğer bu blok çalışırsa hatanın TypeError kaynaklı olduğunu anlayacağız.
    print("TypeError kaynaklı bir hata meydana geldi.") #Sonuç: TypeError kaynaklı bir hata meydana geldi.
except: #eğer bu blok çalışırsa hatanın NameError ya da TypeError kaynaklı olmadığını, başka bir sebepten dolayı meydana geldiğini anlayacağız.
    print("NameError ya da TypeError kaynaklı olmayan bir hata meydana geldi.") #Sonuç: NameError ya da TypeError kaynaklı olmayan bir hata meydana geldi.   


#x değişkeni print öncesinde tanımlanmadığı için NameError kaynaklı bir hata örneği.
try:
    print(x)
except NameError: #eğer bu blok çalışırsa hatanın NameError kaynaklı olduğunu anlayacağız.
    print("NameError kaynaklı bir hata meydana geldi.") #Sonuç: NameError kaynaklı bir hata meydana geldi.   
except TypeError: #eğer bu blok çalışırsa hatanın TypeError kaynaklı olduğunu anlayacağız.
    print("TypeError kaynaklı bir hata meydana geldi.") #Sonuç: TypeError kaynaklı bir hata meydana geldi.
except: #eğer bu blok çalışırsa hatanın NameError ya da TypeError kaynaklı olmadığını, başka bir sebepten dolayı meydana geldiğini anlayacağız.
    print("NameError ya da TypeError kaynaklı olmayan bir hata meydana geldi.") #Sonuç: NameError ya da TypeError kaynaklı olmayan bir hata meydana geldi. 


#3/0 tanımsız olacağı için ZeroDivisionError hatası örneği.
try:
    print(3/0) # Burada ZeroDivisionError hatası var. except bloklarında spesifik olarak belirtilmediği için sondaki except bloğu çalışacaktır.
except NameError: #eğer bu blok çalışırsa hatanın NameError kaynaklı olduğunu anlayacağız.
    print("NameError kaynaklı bir hata meydana geldi.") #Sonuç: NameError kaynaklı bir hata meydana geldi.   
except TypeError: #eğer bu blok çalışırsa hatanın TypeError kaynaklı olduğunu anlayacağız.
    print("TypeError kaynaklı bir hata meydana geldi.") #Sonuç: TypeError kaynaklı bir hata meydana geldi.
except: #eğer bu blok çalışırsa hatanın NameError ya da TypeError kaynaklı olmadığını, başka bir sebepten dolayı meydana geldiğini anlayacağız.
    print("NameError ya da TypeError kaynaklı olmayan bir hata meydana geldi.") #Sonuç: NameError ya da TypeError kaynaklı olmayan bir hata meydana geldi. 
     

#Herhangi bir hatanın oluşmadığı örnek.
x = "ishakkutlu.com"
try:
    print(x) #Hata oluşmayacağı için sadece try bloğu çalışacaktır. except blokları çalışmayacaktır.
except NameError: #eğer bu blok çalışırsa hatanın NameError kaynaklı olduğunu anlayacağız.
    print("NameError kaynaklı bir hata meydana geldi.") #Sonuç: NameError kaynaklı bir hata meydana geldi.   
except TypeError: #eğer bu blok çalışırsa hatanın TypeError kaynaklı olduğunu anlayacağız.
    print("TypeError kaynaklı bir hata meydana geldi.") #Sonuç: TypeError kaynaklı bir hata meydana geldi.
except: #eğer bu blok çalışırsa hatanın NameError ya da TypeError kaynaklı olmadığını, başka bir sebepten dolayı meydana geldiğini anlayacağız.
    print("NameError ya da TypeError kaynaklı olmayan bir hata meydana geldi.") #Sonuç: NameError ya da TypeError kaynaklı olmayan bir hata meydana geldi.

Python’da yukarıda gösterildiği gibi string olarak ayıklanabilen hata türlerinin bazıları aşağıdaki tabloda listelenmiştir.

Aşağıdaki örnekte ise kodların bulunduğu dosya dizininde yer almayan TestFile.py isimli dosyanın açılmaya çalışılması durumunda oluşan hata işlenmiştir. Diğer bir ifadeyle olmayan bir dosya açılmaya çalışılmış ve FileNotFoundError hatası işlenmiştir.

# Bu dosyanın bulunduğu dizinde (klasörde) TestFile.py isimli bir dosya yok.
try:
    with open('TestFile.py') as file: # TestFile.py isimli olmayan dosyayı açmaya çalışacak, ancak hata oluşacağı için except bloğu çalışacaktır.
        read_data = file.read()
except FileNotFoundError as myError:
    print("Şöyle bir hata yazdırılacak:", myError)

3.  Python’da Hatanın Yokluğu Durumu (else bloğu)

Yukarıdaki örneklerden de anlaşılacağı üzere, herhangi bir hatanın meydana gelmemesi durumunda “try” bloğu çalışmaktadır. Ayrıca söz konusu yapıya, “try” bloğuna ek olarak aşağıda gösterildiği gibi “else” bloğu da ilave edilebilir.

#Herhangi bir hatanın oluşmadığı örnek.
x = "ishakkutlu.com"
try:
    print(x) #Hata oluşmayacağı için sadece try bloğu çalışacaktır. except blokları çalışmayacaktır. Hata oluşmayacağı için else bloğu da çalışacaktır.
except NameError: #eğer bu blok çalışırsa hatanın NameError kaynaklı olduğunu anlayacağız.
    print("NameError kaynaklı bir hata meydana geldi.") #Sonuç: NameError kaynaklı bir hata meydana geldi.   
except TypeError: #eğer bu blok çalışırsa hatanın TypeError kaynaklı olduğunu anlayacağız.
    print("TypeError kaynaklı bir hata meydana geldi.") #Sonuç: TypeError kaynaklı bir hata meydana geldi.
except: #eğer bu blok çalışırsa hatanın NameError ya da TypeError kaynaklı olmadığını, başka bir sebepten dolayı meydana geldiğini anlayacağız.
    print("NameError ya da TypeError kaynaklı olmayan bir hata meydana geldi.") #Sonuç: NameError ya da TypeError kaynaklı olmayan bir hata meydana geldi.
else:
    print("Herhangi bir hata meydana gelmedi.") #Sonuç: Herhangi bir hata meydana gelmedi.


#3/0 tanımsız olacağı için ZeroDivisionError hatası örneği.
try:
    print(3/0) # Burada ZeroDivisionError hatası var. except bloklarında spesifik olarak belirtilmediği için sondaki except bloğu çalışacaktır.
except NameError: #eğer bu blok çalışırsa hatanın NameError kaynaklı olduğunu anlayacağız.
    print("NameError kaynaklı bir hata meydana geldi.") #Sonuç: NameError kaynaklı bir hata meydana geldi.   
except TypeError: #eğer bu blok çalışırsa hatanın TypeError kaynaklı olduğunu anlayacağız.
    print("TypeError kaynaklı bir hata meydana geldi.") #Sonuç: TypeError kaynaklı bir hata meydana geldi.
except: #eğer bu blok çalışırsa hatanın NameError ya da TypeError kaynaklı olmadığını, başka bir sebepten dolayı meydana geldiğini anlayacağız.
    print("NameError ya da TypeError kaynaklı olmayan bir hata meydana geldi.") #Sonuç: NameError ya da TypeError kaynaklı olmayan bir hata meydana geldi.
else: #NameError ya da TypeError kaynaklı olmayan bir hata meydana geldiği için sadece except bloğu çalışacaktır.
    print("Herhangi bir hata meydana gelmedi.") #Sonuç: Herhangi bir hata meydana gelmedi.

4.  Python’da Hata Ayıklama Sonucu (finally bloğu)

“try” bloğu bir hata döndürsün ya da döndürmesin “finally” bloğu her durumda çalışır ve “try except” sürecinin sonlandığını ifade eder.

#Herhangi bir hatanın oluşmadığı örnek.
x = "ishakkutlu.com"
try:
    print(x) #Hata oluşmayacağı için sadece try bloğu çalışacaktır. except blokları çalışmayacaktır. Hata oluşmayacağı için else bloğu da çalışacaktır. "finally" her durumda bloğu çalışacaktır.
except NameError: #eğer bu blok çalışırsa hatanın NameError kaynaklı olduğunu anlayacağız.
    print("NameError kaynaklı bir hata meydana geldi.") #Sonuç: NameError kaynaklı bir hata meydana geldi.   
except TypeError: #eğer bu blok çalışırsa hatanın TypeError kaynaklı olduğunu anlayacağız.
    print("TypeError kaynaklı bir hata meydana geldi.") #Sonuç: TypeError kaynaklı bir hata meydana geldi.
except: #eğer bu blok çalışırsa hatanın NameError ya da TypeError kaynaklı olmadığını, başka bir sebepten dolayı meydana geldiğini anlayacağız.
    print("NameError ya da TypeError kaynaklı olmayan bir hata meydana geldi.") #Sonuç: NameError ya da TypeError kaynaklı olmayan bir hata meydana geldi.
else:
    print("Herhangi bir hata meydana gelmedi.") #Sonuç: Herhangi bir hata meydana gelmedi.
finally:
  print("'try except' bloğu tamamlandı.") #Sonuç: 'try except' bloğu tamamlandı.


#3/0 tanımsız olacağı için ZeroDivisionError hatası örneği.
try:
    print(3/0) # Burada ZeroDivisionError hatası var. except bloklarında spesifik olarak belirtilmediği için sondaki except bloğu çalışacaktır. "finally" her durumda bloğu çalışacaktır.
except NameError: #eğer bu blok çalışırsa hatanın NameError kaynaklı olduğunu anlayacağız.
    print("NameError kaynaklı bir hata meydana geldi.") #Sonuç: NameError kaynaklı bir hata meydana geldi.   
except TypeError: #eğer bu blok çalışırsa hatanın TypeError kaynaklı olduğunu anlayacağız.
    print("TypeError kaynaklı bir hata meydana geldi.") #Sonuç: TypeError kaynaklı bir hata meydana geldi.
except: #eğer bu blok çalışırsa hatanın NameError ya da TypeError kaynaklı olmadığını, başka bir sebepten dolayı meydana geldiğini anlayacağız.
    print("NameError ya da TypeError kaynaklı olmayan bir hata meydana geldi.") #Sonuç: NameError ya da TypeError kaynaklı olmayan bir hata meydana geldi.
else: #NameError ya da TypeError kaynaklı olmayan bir hata meydana geldiği için sadece except bloğu çalışacaktır.
    print("Herhangi bir hata meydana gelmedi.") #Sonuç: Herhangi bir hata meydana gelmedi.
finally:
  print("'try except' bloğu tamamlandı.") #Sonuç: 'try except' bloğu tamamlandı.

5.  Python’da Uyarı/Hata Mesajı ve Görevin İptal Edilmesi (raise, Exception metodu)

Belirli koşullar sağlanmadığında kullanıcının bilgilendirilerek görevin iptal edilmesi (takip eden satırlardaki kodların Python tarafından derlenmemesi/çalıştırılmaması) için aşağıda gösterildiği gibi “raise” metodu kullanılabilir.

x = 15
#x = 5
if x < 0 or x > 10: #Eğer koşul gerçekleşirse görev iptal edilecektir. Aşağıdaki mesaj hariç, Python hiçbir şey yapmadan prosedürden çıkacaktır.
  raise Exception("Lütfen 0 ile 9 arasında bir rakam giriniz.") #Sonuç: Exception: Lütfen 0 ile 9 arasında bir rakam giriniz.

print("ishakkutlu.com") #Yukarıdaki koşul gerçekleşirse Python bu ve devamındaki satırları çalıştırmayacaktır.
y = 2 + 5
print(y) 

“raise” metodu yukarıda gösterildiği gibi Exception() ile kullanılabilir. Ayrıca aşağıda gösterildiği gibi (yukarıdaki “Python Hata Kodları” isimli tabloda yer alan) hata kodları referans alınarak da kullanılabilir.

x = "ishakkutlu.com"
#x = 3.5
#TypeError uyarısı göster
if not type(x) is float:
  raise TypeError("Sadece float tipinde veri giriniz.") #Sonuç: TypeError: Sadece float tipinde veri giriniz.

print("ishakkutlu.com") #Yukarıdaki koşul gerçekleşirse Python bu ve devamındaki satırları çalıştırmayacaktır.
y = 2 + 5
print(y) 

Alternatif bir örnek olarak aşağıda gösterildiği gibi “ValueError()” şeklinde de kullanılabilir.

import math

x = -4
#x = 4

#ValueError uyarısı göster
if x < 0:
  raise ValueError("Negatif sayıların karekökü alınamaz.") #Sonuç: ValueError: Negatif sayıların karekökü alınamaz.

print(math.sqrt(x)) 

 

 

İshak Kutlu, Veri Bilimi İçin Python Notları

Yorum Yap

İshak Kutlu

Veri & Otomasyon Uzmanı

Kurumsal iş akışlarını düzenleyen veri odaklı otomasyon sistemleri ve makine öğrenmesi tabanlı çözümler geliştirir. Gerçek operasyonel süreçler için ölçeklenebilir ve izlenebilir yapılar tasarlar.

YouTube   YouTube   YouTube   YouTube