functools

您所在的位置:网站首页 wrapexe怎么用 functools

functools

2023-09-12 01:30| 来源: 网络整理| 查看: 265

一个为函数提供缓存功能的装饰器,缓存 maxsize 组传入参数,在下次以相同参数调用时直接返回上一次的结果。用以节约高开销或I/O函数的调用时间。

该缓存是线程安全的因此被包装的函数可在多线程中使用。 这意味着下层的数据结构将在并发更新期间保持一致性。

如果另一个线程在初始调用完成并被缓存之前执行了额外的调用则被包装的函数可能会被多次调用。

由于使用字典来缓存结果,因此传给该函数的位置和关键字参数必须为 hashable。

不同的参数模式可能会被视为具有单独缓存项的不同调用。 例如,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 为 false ,实现通常会将它们视为等价的调用,只缓存一个结果。(有些类型,如 str 和 int ,即使 typed 为 false ,也可能被分开缓存)。

注意,类型的特殊性只适用于函数的直接参数而不是它们的内容。 标量参数 Decimal(42) 和 Fraction(42) 被视为具有不同结果的不同调用。相比之下,元组参数 ('answer', Decimal(42)) 和 ('answer', Fraction(42)) 被视为等同的。

被包装的函数配有一个 cache_parameters() 函数,该函数返回一个新的 dict 用来显示 maxsize 和 typed 的值。 这只是出于显示信息的目的。 改变值没有任何效果。

为了帮助衡量缓存的有效性以及调整 maxsize 形参,被包装的函数会带有一个 cache_info() 函数,它返回一个 named tuple 以显示 hits, misses, maxsize 和 currsize。

该装饰器也提供了一个用于清理/使缓存失效的函数 cache_clear() 。

原始的未经装饰的函数可以通过 __wrapped__ 属性访问。它可以用于检查、绕过缓存,或使用不同的缓存再次装饰原始函数。

缓存会保持对参数的引用并返回值,直到它们结束生命期退出缓存或者直到缓存被清空。

如果一个方法被缓存,则 self 实例参数会被包括在缓存中。 请参阅 我该如何缓存方法调用?

LRU(最久未使用算法)缓存 在最近的调用是即将到来的调用的最佳预测值时性能最好(例如,新闻服务器上最热门文章倾向于每天更改)。 缓存的大小限制可确保缓存不会在长期运行进程如网站服务器上无限制地增长。

一般来说,LRU 缓存只应在你需要重复使用先前计算的值时使用。 因此,缓存有附带影响的函数、每次调用都需要创建不同的可变对象的函数(如生成器和异步函数)或不纯的函数如 time() 或 random() 等是没有意义的。

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

@lru_cache(maxsize=32) def get_pep(num): 'Retrieve text of a Python Enhancement Proposal' resource = 'https://peps.python.org/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)

以下是使用缓存通过 动态规划 计算 斐波那契数列 的例子。

@lru_cache(maxsize=None) def fib(n): if n >> [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()



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3