如何在Python中缓存方法调用?


缓存方法的两种工具是`functools.cached_property()`和`functools.lru_cache()`。这两个模块都是`functools`模块的一部分。`functools`模块用于高阶函数:作用于其他函数或返回其他函数的函数。让我们首先安装并导入`functools`模块:

安装functools

要安装`functools`模块,请使用pip:

pip install functools

导入functools

要导入`functools`:

import functools

让我们逐一了解这两种缓存方法:

cached_property()

适用于计算实例的昂贵属性,这些属性在其他方面实际上是不可变的。

`cached_property`方法仅适用于不接受任何参数的方法。它不会创建对实例的引用。缓存的方法结果只会保留在实例存在的期间。

优点是,当不再使用实例时,缓存的方法结果会立即释放。缺点是,如果实例累积,缓存的方法结果也会累积。它们可能会无限增长。

示例

让我们看一个例子:

class DataSet: def __init__(self, sequence_of_numbers): self._data = tuple(sequence_of_numbers) @cached_property def stdev(self): return statistics.stdev(self._data)

lru_cache

`lru_cache`方法适用于具有可哈希参数的方法。除非采取特殊措施传入弱引用,否则它会创建对实例的引用。

最近最少使用算法的优点是缓存受指定的`maxsize`限制。缺点是实例将一直保留,直到它们从缓存中过期或缓存被清除。

示例

让我们看一个例子:

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

使用缓存计算斐波那契数的示例:

from functools import lru_cache @lru_cache(maxsize=None) def fib(n): if n < 2: return n return fib(n-1) + fib(n-2) print([fib(n) for n in range(16)]) print(fib.cache_info())

输出

[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]
CacheInfo(hits=28, misses=16, maxsize=None, currsize=16)

缓存示例

现在,让我们看一个`functools.cached_property()`和`lru_cache`的完整示例:

from functools import lru_cache from functools import cached_property class Weather: "Lookup weather information on a government website" def __init__(self, station_id): self._station_id = station_id # The _station_id is private and immutable def current_temperature(self): "Latest hourly observation" # Do not cache this because old results # can be out of date. @cached_property def location(self): "Return the longitude/latitude coordinates of the station" # Result only depends on the station_id @lru_cache(maxsize=20) def historic_rainfall(self, date, units='mm'): "Rainfall on a given date" # Depends on the station_id, date, and units.

更新于:2022年9月19日

2K+ 浏览量

开启你的职业生涯

通过完成课程获得认证

开始学习
广告