2011-06-15 146 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