在Python中为每个实例装饰方法

时间:2011-06-15 11:16:33

标签: python decorator

假设我有一些简单的课程

class TestClass:
    def doSomething(self):
        print 'Did something'

我想装饰doSomething方法,例如计算通话次数

class SimpleDecorator(object):
    def __init__(self,func):
        self.func=func
        self.count=0
    def __get__(self,obj,objtype=None):
        return MethodType(self,obj,objtype)
    def __call__(self,*args,**kwargs):
        self.count+=1
        return self.func(*args,**kwargs)

现在这计算了对装饰方法的调用次数,但是我希望有一个每个实例的计数器,这样在

之后
foo1=TestClass()
foo1.doSomething()
foo2=TestClass()

foo1.doSomething.count为1,foo2.doSomething.count为0.据我所知,使用装饰器是不可能的。有没有办法实现这种行为?

2 个答案:

答案 0 :(得分:10)

利用self(即调用该方法的对象)作为参数传递给方法的事实:

import functools

def counted(method):
    @functools.wraps(method)
    def wrapped(obj, *args, **kwargs):
        if hasattr(obj, 'count'): 
            obj.count += 1
        else:
            obj.count = 1
        return method(obj, *args, **kwargs)
    return wrapped

在上面的代码中,我们将对象拦截为方法的修饰版本的obj参数。装饰器的用法非常简单:

class Foo(object):
    @counted
    def do_something(self): pass

答案 1 :(得分:1)

*args的第一个元素不是该方法被调用的对象吗?难道你不能把数量存储在那里吗?