Python ile Decorator Fonksiyonlarının Oluşturulması
Decorator fonksiyonlar, Python ‘da fonksiyonlarımıza dinamik olarak ekstra özellikler eklediğimiz fonksiyonlardır ve decorator fonksiyonların kullanımı kod tekrarı yapmamızı engeller. Flask gibi frameworklerde oldukça fazla kullanılır.
Önce iki sayıyı bölen bir fonksiyon oluşturalım:
def divide(x, y):
return x / y
Sorun şu ki yukarıdaki fonksiyonda matematikte geçersiz olan 0’a bölme olayının izinli olmasıdır. Pekala bir if kontrolü ile bu sorunu çözebiliriz. Fakat bu yazıda decorator kullanarak uygulama içeriğini değiştirmeden ve uygulama üzerinde tekrar tekrar kullanarak esneklik sağlayabiliriz.
def sifirYok(operate):
def inner(x, y):
if y == 0:
print("0'a bölünemez.")
return
return operate(x, y)
return inner
@sifirYok
def bol(x, y):
return x / y
print(bol(5, 0)) # Çıktı "0'a bölünemez." olacaktır.
Başka bir örnek üzerinden inceleyelim.
import time
def kareleriHesapla(sayilar):
sonuc = []
baslama = time.time()
for i in sayilar:
sonuc.append(i**2)
print("Bu fonksiyon " + str(time.time() - baslama) + " saniye sürdü.")
return sonuc
def kupleriHesapla(sayilar):
sonuc = []
baslama = time.time()
for i in sayilar:
sonuc.append(i**3)
print ("Bu fonksiyon " + str(time.time() - baslama) + " saniye sürdü." )
return sonuc
kareleriHesapla(range(100000))
kupleriHesapla(range(100000))
Bir de yukarıdaki fonksiyonu decorator ile kod tekrarını azaltarak yapalım.
import time
def zamanHesapla(func):
def wrapper(sayilar):
baslama = time.time()
sonuc = func(sayilar)
bitis = time.time()
print(func.__name__ + " " + str(bitis-baslama) + " saniye sürdü.")
return sonuc
return wrapper
@zamanHesapla
def kareleriHesapla(sayilar):
sonuc = []
for i in sayilar:
sonuc.append(i**2)
return sonuc
@zamanHesapla
def kupleriHesapla(sayilar):
sonuc = []
for i in sayilar:
sonuc.append(i**3)
return sonuc
kareleriHesapla(range(100000))
kupleriHesapla(range(100000))
Başka bir örneğe daha göz atacak olursak
def ekstra(fonk):
def wrapper(sayilar):
ciftlerToplami = 0
ciftSayilar = 0
teklerToplami = 0
tekSayilar = 0
for sayi in sayilar:
if (sayi % 2 == 0):
ciftlerToplami += sayi
ciftSayilar += 1
else:
teklerToplami += sayi
tekSayilar += 1
print("Teklerin ortalaması: ", teklerToplami / tekSayilar)
print("Çiftlerin ortalaması: ", ciftlerToplami / ciftSayilar)
fonk(sayilar)
return wrapper
@ekstra
def ortalamaBul(sayilar):
toplam = 0
for sayi in sayilar:
toplam += sayi
print("Genel ortalama: ", toplam / len(sayilar))
ortalamaBul([1, 2, 3, 4, 5, 6, 60, 32, 45, 200, 105])
"""
Çıktı:
Teklerin ortalaması: 31.8
Çiftlerin ortalaması: 50.666666666666664
Genel ortalama: 42.09090909090909
"""