为什么 python3 lru_cache 不提供放置和查询方法?

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

这是我的情况,is_exist 函数有性能问题。

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 是一个很好的解决方案,但经过几个小时的努力后我发现 lru_cache 不符合我的要求。我想要这样的:

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

functiontools中的LRU Cache是​​一个装饰器。它没有查询方法。如果我使用 @lru_cache 装饰 is_exist 某些 link 将在 is_exist return false.

时重复处理

PS: 将结果放入数据库是异步的

典型用法lru_cache

我不确定你为什么不申请 lru_cache 作为装饰器:

@lru_cache(maxsize=None)
def is_exist(link :str) -> bool:
    if query_db(link) is True:
         return True
    return False

只要重复调用 is_exist 将使用相同的参数 link 缓存就会有效。

请注意maxsize=None,这将确保缓存大小的限制远大于默认的 128(并且仅受 RAM 大小限制)。

自己实现缓存

lru_cache 不提供根据函数的 return 值缓存结果的灵活性。但是,您可以使用 set:

自己轻松实现它
cache = set()

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

def process(link: str)
   if link in cache:
      return True

   if is_exist(link) is True:
       cache.add(link)
       return

您需要 link 的测试,如果它不存在,则在同一个调用中创建它 - 可能最简单的方法是删除缓存的 is_exists 并缓存 process()功能,但将其重命名为例如ensure_link:

@lru_cache
def ensure_link(link: str)
   if query_db(link) is True:
       return
   # do something
   # put result to database
   return

要么那样做,要么在函数属性或类似属性中自己进行缓存 - 这不是很困难

functools.lru_cache 仅缓存 结果 但不缓存异常。这意味着函数应该在以后必须重新评估的任何情况下引发异常。

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

这允许客户端功能检查 – 使用缓存 – 但仍然插入丢失的条目。

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