Python 如何缓存方法调用
缓存方法的两个工具是functools.cached_property()和functools.lru_cache()。两个模块均属于functools模块。functools模块用于高阶函数:即作用于其他函数或返回其他函数的函数。让我们首先安装并导入functools模块−
安装functools
要安装functools模块,请使用pip−
pip install functools
导入functools
导入functools,使用以下代码 −
import functools
让我们逐个了解缓存的方法 –
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方法适用于具有可哈希参数的方法。它会创建对实例的引用,除非采取特殊措施传递弱引用。
最近最少使用(LRU)算法的优点是缓存受到指定的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.