I was reading about decorators and tried to mix these two examples and make them class decorators instead of regular functions. The first one only lets you run a function once per argument and the second one counts how many times you've run that function. They both work fine separated but when I try to decorate a simple function with both at the same time it fails... Or doesn't really fail but prints an unexpected wrong result. I did some reading and found that the functools module can help but I'm not sure how.
from functools import update_wrapper
class Memoize:
def __init__(self, func):
self.func = func
self.memo = dict()
update_wrapper(self, func)
def __call__(self, *args):
if args not in self.memo:
self.memo[args] = self.func(args)
else:
print("cls decorator. You have printed this before")
return self.memo[args]
class CallCounter:
def __init__(self, func):
self.func = func
self.calls = 0
self.__name__ = func.__name__
update_wrapper(self, func)
def __call__(self, *args, **kwargs):
self.calls += 1
return self.func(*args, **kwargs)
@Memoize
@CallCounter
def doubleprint(x):
for elem in x:
print(elem + " " + elem)
doubleprint('Hello')
doubleprint('Hello')
doubleprint('Hello')
doubleprint('Hello')
doubleprint('Bye')
print(doubleprint.calls)
doubleprint('Hello')
doubleprint('Hello')
doubleprint('Hello')
doubleprint('Hello')
doubleprint('Bye')
print(doubleprint.calls)