简体   繁体   中英

Recursion in closures Python

# -*- coding: utf-8 -*-

def memoize(limit, *, message = 'Limit exceded'):
    count = 0
    def inner(func):
        cache = {}
        def wrapped(number):
            nonlocal count
            if count < limit:
                if number not in cache:
                    cache[number] = func(number)
                count += 1
                return cache[number]
            print(message)
        return wrapped
    return inner

@memoize(5)
def fat(x):
    if x < 2:
        return 1
    return x * fat(x - 1)

In theory the algorithm should receive a number that would set a storage limit of the results in a cache, instead of raising an exception I simply show the message that was passed or the default ("Limit exceded") in case the limit number in the cache is reached . The problem is that it only runs the program only once and shows the message, but where is the error ???

Your code isn't setting a limit on the size of the cache, but on the number of calls to the wrapper:

if number not in cache:
    cache[number] = func(number)
count += 1

In other words, you increment count whether the number was already in the cache or not. To fix that, you just need to indent that increment.


On top of that, the count doesn't get reset for each new cache, because the only place you set it to 0 is in outer function:

def memoize(limit, *, message = 'Limit exceded'):
    count = 0
    def inner(func):
        cache = {}

To fix that, you need to move the count = 0 from memoize to inner . (Or, if you prefer, add a nonlocal count and reset it with count = 0 in inner , but that's just extra work for the same effect.)


But an even simpler fix to both of these problem is to get rid of count entirely. You're trying to count whether you've hit the storage limit in the cache? Just check if len(cache) < limit: .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM