On Mon, Apr 18, 2011 at 6:47 AM, Timo Schmiade <the_...@gmx.de> wrote: > Hi all, > > I'm currently occupying myself with python's decorators and have some > questions as to their usage. Specifically, I'd like to know how to > design a decorator that maintains a status. Most decorator examples I > encountered use a function as a decorator, naturally being stateless. > > Consider the following: > > def call_counts(function): > @functools.wraps(function): > def wrapper(*args, **kwargs): > # No status, can't count #calls. > return function(*args, **kwargs) > return wrapper
In the simple case, just store the state on the wrapper function itself: def call_counts(function): @functools.wraps(function) def wrapper(*args, **kwargs): wrapper.num_calls += 1 return function(*args, **kwargs) wrapper.num_calls = 0 return wrapper @call_counts def f(): pass f() f() print(f.num_calls) > * The maintained status is not shared among multiple instances of the > decorator. This is unproblematic in this case, but might be a problem > in others (e.g. logging to a file). If you want the state to be shared, you should probably store it in an object and use an instance method as the decorator: class CallCounter(object): def __init__(self): self.num_calls = 0 def call_counts(self, function): @functools.wraps(function) def wrapper(*args, **kwargs): self.num_calls += 1 return function(*args, **kwargs) return wrapper call_counter = CallCounter() @call_counter.call_counts def f1_with_shared_counts(): pass @call_counter.call_counts def f2_with_shared_counts(): pass Cheers, Ian -- http://mail.python.org/mailman/listinfo/python-list