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
"""

 

 

Kaynak


Abone ol
Bildir
guest
0 Yorum
Satır İçi Geri Bildirimler
Tüm yorumları görüntüle