How to create a (transparent) decorator with status information?

Timo Schmiade the_isz at gmx.de
Mon Apr 18 08:47:02 EDT 2011


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
Thinking object-orientedly, my first idea was to use an object as a
decorator:
class CallCounter:
 def __init__(self, decorated):
 self.__function = decorated
 self.__numCalls = 0
 def __call__(self, *args, **kwargs):
 self.__numCalls += 1
 return self.__function(*args, **kwargs)
 # To support decorating member functions
 def __get__(self, obj, objType):
 return functools.partial(self.__call__, obj)
This approach however has three problems (let "decorated" be a function
decorated by either call_counts or CallCounter):
* The object is not transparent to the user like call_counts is. E.g.
 help(decorated) will return CallCounter's help and decorated.func_name
 will result in an error although decorated is a function.
* 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).
* I can't get the information from the decorator, so unless CallCounter
 emits the information on its own somehow (e.g. by using print), the
 decorator is completely pointless.
So, my question is: What would the "pythonic" way to implement a
decorator with status information be? Or am I missing the point of
decorators and am thinking in completely wrong directions?
Thanks in advance!
Kind regards,
Timo


More information about the Python-list mailing list

AltStyle によって変換されたページ (->オリジナル) /