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