我想用一个decorator来做一些准备工作并记录函数的状态,所以我写了这样的东西:
class Decorator:
def __init__(self, func):
self.count = 0
self.func = func
def __call__(self, *args, **kwargs):
self.count += 1 # Simply count the call times
return self.func(self, *args, **kwargs)
class Foo:
def __init__(self):
self.value = 0
@Decorator
def test(self, value):
self.value = value # change the value of instance
print(self.value)
f = Foo()
f.test(1)
print(f.value)
print(f.test.value)
但很明显,
self
中的__call__(self, *args, **kwargs)
对应于Decorator
的实例,而不是Foo
的实例,这将使f.value
保持不变,但f.test.value
增加。有什么方法可以将
Foo
的实例传递给Decorator
而不是Decorator
本身吗?或者有什么方法可以更清楚地实现这个功能?
提前谢谢。
最佳答案
因为decorator只调用一次,并用decorator类的一个实例替换所有实例的方法。它所做的就是:
Foo.test = Decorator(Foo.test)
这使得无法检测调用的实例。一种解决方法是手动应用
__init__
的Foo
中的decorator:class Foo:
def __init__(self):
self.value = 0
self.test = Decorator(self.test)
def test(self, value):
self.value = value # change the value of instance
print(self.value)
这样,decorator包装实例方法,因此您不需要在
self
的__call__
中传递Decorator
:class Decorator:
def __init__(self, func):
self.count = 0
self.func = func
def __call__(self, *args, **kwargs):
self.count += 1 # Simply count the call times
return self.func(*args, **kwargs)
现在它工作了,你必须更新你的测试方法,因为
f.test.value
不再存在:f = Foo()
f.test(1)
print(f.value)
它输出两倍于预期的a
1
。关于python - 类作为类方法的装饰器,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37792257/