The code is right (with the only detail that does not make sense to keep the variable count
alone in memoize
- it should either be within inner
, or cache
should be out, along with it , but that's aesthetic).
What happens is that your decorated function is itself recursive , that is, a single call to fat
will call the decorator wrapper n times: hence it already burst its limit of 5 calls. Increase the call limit, or make the call to fat with a smaller number and you will see that it is.
If you want incoming calls to fat not to the limit, you can put a counter to detect recursion, and do not increase the% of internal% in that case (and there, be careful that things start to get complicated if the program is multi-threaded, this recursion counter has to be a thread-local variable)
def memoize(limit, *, message = 'Limit exceded'):
def inner(func):
count = 0
cache = {}
recursing = 0
def wrapped(number):
nonlocal count, recursing
if count < limit:
recursing += 1
if number not in cache:
cache[number] = func(number)
recursing -= 1
if not recursing:
count += 1
return cache[number]
print(message)
return wrapped
return inner