当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


Python functools.lru_cache用法及代码示例


用法:

@functools.lru_cache(user_function)
@functools.lru_cache(maxsize=128, typed=False)

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

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

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

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

@lru_cache
def count_vowels(sentence):
    return sum(sentence.count(vowel) for vowel in 'AEIOUaeiou')

如果 maxsize 设置为 None ,则禁用 LRU 函数,并且缓存可以无限制地增长。

如果typed设置为true,不同类型的函数参数将分别缓存。如果typed 为假,实现通常会将它们视为等效调用并仅缓存单个结果。 (某些类型,例如strint,即使typed 为假,也可能被单独缓存。)

请注意,类型特异性仅适用于函数的直接参数,而不适用于它们的内容。标量参数 Decimal(42)Fraction(42) 被视为具有不同结果的不同调用。相反,元组参数('answer', Decimal(42))('answer', Fraction(42)) 被视为等效。

包装的函数使用 cache_parameters() 函数进行检测,该函数返回一个新的 dict ,显示 maxsizetyped 的值。这仅供参考。改变值没有效果。

为了帮助测量缓存的有效性并调整 maxsize 参数,包装函数使用 cache_info() 函数进行检测,该函数返回显示 hits , misses , maxsizecurrsize 的命名元组。

装饰器还提供了一个cache_clear() 函数用于清除或使缓存无效。

原始底层函数可通过__wrapped__ 属性访问。这对于自省、绕过缓存或使用不同的缓存重新包装函数很有用。

缓存保留对参数和返回值的引用,直到它们超出缓存或缓存被清除。

当最近的调用是即将到来的调用的最佳预测指标时,LRU (least recently used) cache 效果最好(例如,新闻服务器上最受欢迎的文章往往每天都在变化)。缓存的大小限制确保缓存不会不受限制地增长 long-running 进程,例如 Web 服务器。

一般来说,LRU 缓存应该只在你想重用之前计算的值时使用。因此,使用side-effects 缓存函数、需要在每次调用时创建不同的可变对象的函数或诸如time() 或random() 之类的不纯函数是没有意义的。

静态 Web 内容的 LRU 缓存示例:

@lru_cache(maxsize=32)
def get_pep(num):
    'Retrieve text of a Python Enhancement Proposal'
    resource = 'https://www.python.org/dev/peps/pep-%04d/' % num
    try:
        with urllib.request.urlopen(resource) as s:
            return s.read()
    except urllib.error.HTTPError:
        return 'Not Found'

>>> for n in 8, 290, 308, 320, 8, 218, 320, 279, 289, 320, 9991:
...     pep = get_pep(n)
...     print(n, len(pep))

>>> get_pep.cache_info()
CacheInfo(hits=3, misses=8, maxsize=32, currsize=8)

使用缓存高效计算 Fibonacci numbers 以实现 dynamic programming 技术的示例:

@lru_cache(maxsize=None)
def fib(n):
    if n < 2:
        return n
    return fib(n-1) + fib(n-2)

>>> [fib(n) for n in range(16)]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]

>>> fib.cache_info()
CacheInfo(hits=28, misses=16, maxsize=None, currsize=16)

3.2 版中的新函数。

在 3.3 版中更改:添加了typed选项。

在 3.8 版中更改:添加了user_function选项。

3.9 版中的新函数:增加了函数cache_parameters()

相关用法


注:本文由纯净天空筛选整理自python.org大神的英文原创作品 functools.lru_cache。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。