sınıfında kullanıldığında başarısız olur Sınıf yöntemlerinde kullanmak üzere dekoratörler oluştururken, dekoratör mekanizması bir işlev/kapatma yerine bir sınıf olduğunda sorun yaşıyorum. Sınıf formu kullanıldığında, dekolayıcım bağlı bir yöntem olarak ele alınmaz.Sınıf üyelerindeki Python dekoratörleri, dekoratör mekanizması sınıf
Genellikle dekoratörler için işlev formunu kullanmayı tercih ediyorum ancak bu durumda ihtiyacım olanı uygulamak için mevcut bir sınıfı kullanmam gerekiyor.
Bu, python-decorator-makes-function-forget-that-it-belongs-to-a-class ile ilişkili gibi görünüyor ama neden işlev formu için sorun çözebilir?
Tüm ziyaretleri göstermek için yapabileceğim en basit örnek aşağıdadır.
def decorator1(dec_param):
def decorator(function):
print 'decorator1 decoratoring:', function
def wrapper(*args):
print 'wrapper(%s) dec_param=%s' % (args, dec_param)
function(*args)
return wrapper
return decorator
class WrapperClass(object):
def __init__(self, function, dec_param):
print 'WrapperClass.__init__ function=%s dec_param=%s' % (function, dec_param)
self.function = function
self.dec_param = dec_param
def __call__(self, *args):
print 'WrapperClass.__call__(%s, %s) dec_param=%s' % (self, args, self.dec_param)
self.function(*args)
def decorator2(dec_param):
def decorator(function):
print 'decorator2 decoratoring:', function
return WrapperClass(function, dec_param)
return decorator
class Test(object):
@decorator1(dec_param=123)
def member1(self, value=1):
print 'Test.member1(%s, %s)' % (self, value)
@decorator2(dec_param=456)
def member2(self, value=2):
print 'Test.member2(%s, %s)' % (self, value)
@decorator1(dec_param=123)
def free1(value=1):
print 'free1(%s)' % (value)
@decorator2(dec_param=456)
def free2(value=2):
print 'free2(%s)' % (value)
test = Test()
print '\n====member1===='
test.member1(11)
print '\n====member2===='
test.member2(22)
print '\n====free1===='
free1(11)
print '\n====free2===='
free2(22)
Çıktı:
decorator1 decoratoring: <function member1 at 0x3aba30>
decorator2 decoratoring: <function member2 at 0x3ab8b0>
WrapperClass.__init__ function=<function member2 at 0x3ab8b0> dec_param=456
decorator1 decoratoring: <function free1 at 0x3ab9f0>
decorator2 decoratoring: <function free2 at 0x3ab970>
WrapperClass.__init__ function=<function free2 at 0x3ab970> dec_param=456
====member1====
wrapper((<__main__.Test object at 0x3af5f0>, 11)) dec_param=123
Test.member1(<__main__.Test object at 0x3af5f0>, 11)
====member2====
WrapperClass.__call__(<__main__.WrapperClass object at 0x3af590>, (22,)) dec_param=456
Test.member2(22, 2) <<<- Badness HERE!
====free1====
wrapper((11,)) dec_param=123
free1(11)
====free2====
WrapperClass.__call__(<__main__.WrapperClass object at 0x3af630>, (22,)) dec_param=456
free2(22)
Soruyu yeniden adlandırmanızı tavsiye ederim. Bu aslında dekoratörlerle ilgili değildir, ancak bir işlev nesnesini bir sınıf yöntemi olarak eklemekten ziyade – Casebash
Genel olarak (her zaman olmasa da), bir soru bu kadar uzun olduğunda sorunu izole ederek basitleştirilebilir. Örneğin, sınıfa el ile not eklemeyi denemiş olsaydınız, bunun dekoratörlerle hiçbir ilgisi olmadığını fark edersiniz ve muhtemelen bu kodun tamamını yazmanız daha hızlı olurdu. – Casebash