Python Decoratorler kolay bir soru

Arkadaşlar global’de açtığım bir fonksiyonu clas içindeki bir fonksiyona nasıl decorate edebilirim.

Örneğin

import time

def zaman(func):

    def wrapper():

        başlama = time.time()

        func()

        bitiş = time.time()

        print(func.__name__ + " " + str(bitiş - başlama) + " saniye sürdü.")

    return wrapper()

class Deneme():

    def __init__(self):

        self.abc()

    @zaman
    def abc(self):

        self.a = input("a: ")
        self.b = input("b: ")

        print(self.a + self.b)

deneme = Deneme

deneme.abc()

Bu çalışmıyor, diyelim ki 6 tane class oluşturacağım her biri için ayrı ayrı yazmak istemiyorum. "zaman()"ı .self ile yazmaktan başka çözüm var mı?

Merhaba,

wrapper'a self için bir argüman yazmalısınız. Ayrıca return wrapper() yerine return wrapper yazmanız gerekiyor.

Aşağıdaki kodları inceleyin:

import time


def zaman(func):
    def wrapper(x):
        başlama = time.time()
        func(x)
        bitiş = time.time()
        print(
            func.__name__ + 
            " " + 
            str(bitiş - başlama) + 
            " saniye sürdü."
        )
    return wrapper


class Deneme():
    def __init__(self):
        self.abc()

    @zaman
    def abc(self):
        self.a = input("a: ")
        self.b = input("b: ")
        print(self.a + self.b)


deneme = Deneme()
2 Beğeni

Yazbelin Decorator fonksiyonlar için bir dokümantasyonu var mıdır? Bir türlü anlayamadığım bir mesele çünkü :frowning:
Ya da bildiğiniz başka güzel bir kaynak?

1 Beğeni

Bu konuyla alakalı bir başlık vardı daha önce, oradaki bilgilerin yeterli olabileceğini tahmin ediyorum.

3 Beğeni

Verilen hatanın sebebi return wrapper() satırında çağırılan wrapper fonksiyonun içindeki func() bölümü. func burada Deneme.abc oluyor ve bu fonksiyon self argümanı alıyor. Ama siz func'u çağırırken bu argümanı vermiyorsunuz.

Koddaki diğer bir hata da deneme = Deneme satırında. Burada Deneme sınıfının bir örneğini oluşturmak yerine deneme değişkenine Deneme sınıfını atıyorsunuz. Bu şekilde deneme.abc()'nin Deneme.abc()'den bir farkı yok.

Bezeyiciyi nasıl yazacağınıza gelince, ilk olarak return wrapper() yerine return wrapper yazmanız lazım. Burada amacımız wrapper fonksiyonunu döndürmek, wrapper fonksiyonunu çağırıp dönüş değeri olan None'u döndürmek değil.

İkinci olarak da zaman bezeyicisinin genel kullanıma uygun olması için *args, **kwargs kullanılması lazım:

import time

def zaman(func):

    def wrapper(*args, **kwargs):

        başlama = time.time()

        func(*args, **kwargs)

        bitiş = time.time()

        print(func.__name__ + " " + str(bitiş - başlama) + " saniye sürdü.")

    return wrapper

class Deneme():

    def __init__(self):
        pass

    @zaman
    def abc(self):

        self.a = input("a: ")
        self.b = input("b: ")

        print(self.a + self.b)

deneme = Deneme()

deneme.abc()
2 Beğeni