python lru_cache 中的单位是什么?

Sör*_*ren 4 python functools

根据文档,lru_cachefrom的默认值functools是 128。但没有定义单位。

装饰器用记忆调用来包装函数,最多保存最近调用的 maxsize。当使用相同的参数定期调用昂贵的或 I/O 绑定的函数时,它可以节省时间。

由于字典用于缓存结果,因此函数的位置和关键字参数必须是可散列的。

不同的参数模式可以被认为是具有单独缓存条目的不同调用。例如,f(a=1, b=2) 和 f(b=2, a=1) 的关键字参数顺序不同,可能有两个单独的缓存条目。

如果指定了 user_function,则它必须是可调用的。这允许将 lru_cache 装饰器直接应用于用户函数,将 maxsize 保留为其默认值 128。

我的问题是有没有像位、字节、兆字节这样的单位附加到这个或这是一个与使用的内存没有简单关系的任意数字?

Wil*_*sem 6

简短回答:它是存储在缓存中的元素数量。

我们可以查找lru_cache[GitHub]的源代码。代码比较复杂,但简而言之,619行已经给出了线索​​:

                    full = (cache_len() >= maxsize)
Run Code Online (Sandbox Code Playgroud)

这指定缓存已满,因为cache_len()大于或等于maxsize。

这cache_len是一个返回字典中记录数的函数,正如我们在源代码中看到的:

    cache = {}
    hits = misses = 0
    full = False
    cache_get = cache.get    # bound method to lookup a key or return None
    cache_len = cache.__len__  # get cache size without calling len()
Run Code Online (Sandbox Code Playgroud)

每次添加新记录时,逻辑也会发生分支,如果缓存已满,它将“踢出”其中一个元素:

                if key in cache:
                    # Getting here means that this same key was added to the
                    # cache while the lock was released.  Since the link
                    # update is already done, we need only return the
                    # computed result and update the count of misses.
                    pass
                elif full:
                    # Use the old root to store the new key and result.
                    oldroot = root
                    oldroot[KEY] = key
                    oldroot[RESULT] = result
                    # Empty the oldest link and make it the new root.
                    # Keep a reference to the old key and old result to
                    # prevent their ref counts from going to zero during the
                    # update. That will prevent potentially arbitrary object
                    # clean-up code (i.e. __del__) from running while we're
                    # still adjusting the links.
                    root = oldroot[NEXT]
                    oldkey = root[KEY]
                    oldresult = root[RESULT]
                    root[KEY] = root[RESULT] = None
                    # Now update the cache dictionary.
                    del cache[oldkey]
                    # Save the potentially reentrant cache[key] assignment
                    # for last, after the root and links have been put in
                    # a consistent state.
                    cache[key] = oldroot
                else:
                    # Put result in a new link at the front of the queue.
                    last = root[PREV]
                    link = [last, root, key, result]
                    last[NEXT] = root[PREV] = cache[key] = link
                    # Use the cache_len bound method instead of the len() function
                    # which could potentially be wrapped in an lru_cache itself.
                    full = (cache_len() >= maxsize)
Run Code Online (Sandbox Code Playgroud)