T
Timo Schmiade
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
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