Python 类作为类方法的装饰器

Python 类作为类方法的装饰器,python,decorator,Python,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.f

我想使用一个装饰器来做一些准备工作,并记录函数的状态,所以我写了如下内容:

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
对应于
Decorator
的实例,而不是
Foo
的实例,这将使
f.value
保持不变,但
f.test.value
增加

有没有办法将
Foo
的实例传递给
Decorator
而不是
Decorator
本身

或者有没有更清晰地实现这一功能的方法


感谢高级版。

因为decorator只被调用一次,并且用decorator类的一个实例替换了所有实例的方法。它所做的只是:

这使得无法检测调用的实例。一种解决方法是手动在
Foo
\uuuu init\uuuu
中应用装饰器:

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)
这样,装饰器包装实例方法,因此您不需要在
装饰器的
调用中传递
self

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)
它按预期输出两次
1

我得到了这个

可能是这个

def preJob(function):
    def updateToDo(self, *args, **kwargs):
        # do some recording
        function(self, *args, **kwargs)
    return updateToDo

class Foo(object):
    def __init__(self):
        self.value = 0

    @preJob
    def test(self, value):
        self.value = value

f = Foo()
f.test(3)
print(f.value)  # prints 3


g = Foo()
g.test(8)
print(g.value) # prints 8
我发现,使用Priyesh Kumar的答案,您可以简单地将自变量从调用方法传递到被修饰的函数:

def __call__(self, *args, **kwargs):
    return self.SafeGenerator(self.func(self, *args, **kwargs))
希望这有帮助

编辑:
仅当通过decorator传递的函数不调用init方法中定义的类变量时,“别管”才起作用

f.test.value做什么?我200%确定我没有完全理解您的问题。正如在代码中一样,您希望记录调用@Decorator方法的次数。那很好,但你以后怎么才能查到那笔钱。我试过一个例子,在这个例子中,您可以将Foo的实例传递给Decorator,但f.test.value不起作用。您可以使用
f.test.count
访问计数,其中
f
Foo
的实例。
def preJob(function):
    def updateToDo(self, *args, **kwargs):
        # do some recording
        function(self, *args, **kwargs)
    return updateToDo

class Foo(object):
    def __init__(self):
        self.value = 0

    @preJob
    def test(self, value):
        self.value = value

f = Foo()
f.test(3)
print(f.value)  # prints 3


g = Foo()
g.test(8)
print(g.value) # prints 8
class threadSafeGenerator(object):
    """docstring for threadSafeGenerator"""
    class SafeGenerator(object):
        """docstring for SafeGenerator"""
        def __init__(self, iterable):
            self.iterable = iterable
            self.lock = Lock()
        def __iter__(self):
            return self

        def __next__(self):
            with self.lock:
                return next(self.iterable)

    def __init__(self, func):
        super(threadSafeGenerator, self).__init__()
        self.func = func

    def __call__(self, *args, **kwargs):
        return self.SafeGenerator(self.func(self, *args, **kwargs))
def __call__(self, *args, **kwargs):
    return self.SafeGenerator(self.func(self, *args, **kwargs))