2011-06-15 85 views
5

假设我有一些简单的类装饰方法在Python

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.根据我的理解,这是不可能使用装饰器。有什么方法可以实现这种行为?

回答

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

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

+0

是的,我想这是可能的。但是对我来说,这感觉就像是一个不理想的设计,因为装饰者会依赖它所使用的类的属性来使它更难使用。 – Christoph 2011-06-15 11:27:00