Search code examples
pythonpython-3.xcachinglru

why python3 lru_cache doesn't offer an put and query method?


here is my situation, the is_exist function has performance matter.

def is_exist(link :str) -> bool:
    if query_db(link) is True:
         return True
    return False

def process(link: str)
   if is_exist(link) is True:
       return
   # do something
   # put result to database

LRU Cache is a good solution, but after struggle hours i found lru_cache doesn't meet my requirments. What i want like this:

def is_exist(link :str) -> bool:
    if query_db(link) is True:
         return True
    return False

def process(link: str)
   if lru_cache.query(link) is True:
      return

   if is_exist(link) is True:
       lru_cache.add(link)
       return
   # do something
   # put result to database

The LRU Cache in functiontools is a decorator. It doesn't have a query method. If I use @lru_cache decorates is_exist some link will be processed repeatedly when is_exist return false.

PS: put result to db is async


Solution

  • functools.lru_cache only caches results but not exceptions. This means functions should raise an exception in any situation that must be re-evaluated later on.

    @lru_cache
    def is_exist(link: str) -> bool:
        if query_db(link):
             return True   # added to cache
        raise LookupError  # ignored by cache
    

    This allows the client function to check – with cache – but still insert missing entries.

    def process(link: str)
       try:
           is_exist(link)
       except LookupError:
           # do something
           # put result to database