Python Cachetools模块
我们中的大多数人应该听说过’Cache’这个词,但并不是所有听过这个词的人都了解它。计算机技术方面的缓存是一种存储用户在计算机上执行的操作的数据(的软件或硬件组件)。当以后对同样的数据发出请求时,因为相同的数据将更快地提供,所以缓存非常有帮助。系统的缓存组件中存储的数据可能是因为先前执行的计算,或者相同数据的副本存储在其他地方。因此,我们可以看到缓存对于更快的计算和更好的结果在较短时间内非常重要。与实际数据的实际大小相比,缓存占用的空间非常小,因此对用户来说更有用。
Python为我们提供了各种模块,通过这些模块,我们可以处理系统中存在的缓存内存。Python还为我们提供了可以利用缓存内存进行更快计算和节省时间的模块。其中一种Python模块是Python的Cachetools模块,我们将在本教程中学习有关此模块的知识。我们将简要详细了解Python中的Cachetools模块及其功能,以及如何使用系统中的缓存来执行各种任务。
Python中的Cachetools模块
Cachetools模块:简介
Cachetools是一个Python模块,它为我们提供了各种装饰器(即此模块中提供的函数)和记忆集合。Cachetools帮助我们有效地处理系统中的缓存,并且我们可以使用Cachetools模块来加快Python程序的处理速度。Cachetools模块还包括Functools模块的一些变体(另一个Python模块)的@lru_cache装饰器函数。
Cachetools模块:安装
Cachetools模块不是Python的内置模块,因此如果我们想在系统中使用此模块及其功能,我们首先必须安装此模块。在本节中,我们将通过pip安装程序在命令提示符终端中安装Cachetools模块。首先,我们必须打开命令提示符终端,然后在终端中编写以下pip命令:
pip install cachetools
当我们按下回车键时,pip安装程序将通过终端在我们的系统中开始安装Cachetools模块。
正如我们所看到的,Cachetools模块已成功安装到我们的系统中,现在我们可以在Python程序中调用该模块,通过Python来处理我们系统中的缓存。
Cachetools模块:函数
在这里,我们只讨论Python的Cachetools模块中存在的函数。我们应该注意到,这些函数是Python中的装饰器函数类型,当我们使用这些函数时,它们将在程序中作为装饰器函数使用。
以下是Cachetools模块中存在的五个函数:
- 缓存(cached)
- TTLCache
- RRCache
- LRUCache
- LFUCache
现在,我们将详细学习上述所有函数,并通过在Python程序中使用每个函数来了解它们的工作原理。
缓存函数(Cached Function)
Cachetools模块的缓存函数在Python中作为装饰器函数使用,它默认在程序中执行简单的缓存。当我们使用缓存装饰器调用一个函数时,它将缓存我们调用的函数,以便以后使用它作为缓存。
语法:
以下是在Python程序中使用缓存装饰器函数的语法:
@cached(cache = {})
def any_funct():
pass # Code in the function
参数: 在cached装饰器中,我们使用一个名为any_funct()的默认函数(我们甚至可以在函数内部给出参数)。在使用cached装饰器的时候,我们会在默认函数内编写一个逻辑代码,而不是使用一个pass语句。
现在,让我们在Python程序中使用这个cached装饰器来更好地理解它的工作原理以及它如何节省我们的时间。
示例1:
查看以下程序以理解cached装饰器的实现:
# Import cached from Cachetools Module
from cachetools import cached
# Import time module in the program
import time
# Calling a function without using cache
def fiban(n):
return n if n<2 else fiban(n-1) + fiban(n-2)
# Calculating total time for performing operation
totalTime1 = time.time()
# Printing function result
print("Result of operation: ", fiban(31))
# Total time taken
print("Time Taken by function without cache: ", time.time() - totalTime1)
# Calling function using cache
@cached(cache = {})
def fiban(n):
return n if n<2 else fiban(n-1) + fiban(n-2)
# Result of operation performed by function
totalTime2 = time.time()
print("Result of operation: ", fiban(31))
# Now total time taken in Operation
print("Time Taken by function with cached: ", time.time() - totalTime2)
输出:
Result of operation: 1346269
Time Taken by function without cache: 0.8905675411224365
Result of operation: 1346269
Time Taken by function with cached: 0.015604496002197266
说明:
首先,我们从Cachetools模块中导入了cached装饰器函数,以便在程序中使用它。我们还导入了time模块,以便统计时间并检查cached如何使函数调用更快。之后,我们定义了一个默认函数,并使用逻辑代码通过运算来计算值,然后返回运算后的值。当我们在fiban()函数中使用参数来找到实际值时,我们在找出执行此操作所需的时间之前,使用了time()函数。然后,我们打印出在运算中获得的值及执行该操作所需的总时间。之后,我们使用了cached装饰器函数,并定义了相同的默认函数,即fiban()函数,其中包含相同的逻辑。现在,我们再次使用时间函数来计算调用该函数所需的总时间。然后,在fiban()函数中再次给出参数后,我们打印出执行该操作所需的时间和总时间,并带有cached装饰器。
从输出可以看出,当我们在没有使用cached时调用函数时,所花费的时间比使用cached装饰器调用函数时要多得多(当两个函数相同,逻辑完全相同,并在调用时具有相同的参数)。这就是cached装饰器通过将函数保存在缓存内存中并在再次调用时节省大量时间的方式。
TTLCache函数
TTLCache也被称为“存活时间(Time to Live)”缓存,它也是Cachetools模块包中包含的一个装饰器函数。当我们在程序中调用函数时,它也可以在系统中的缓存上工作。但是它与Cachetools模块的先前函数的工作方式有很大不同,我们可以从两个函数的语法中看出这一点。
语法:
以下是在Python程序中使用TTLCache装饰器函数的语法:
# Working on cache
@cached(cache = TTLCache(maxsize = 33, ttl = 600))
# Default function
def anyFunct():
pass # logical code in the function
参数: 与Cached装饰器语法不同,我们在TTLCache装饰器函数中必须提供两个参数。我们还可以看到,在函数中使用参数之前,我们已经指定了缓存类型为TTLCache。以下是我们在TTLCache装饰器内使用的参数:
- maxsize: 在TTLCache函数中使用的maxsize定义了可以存储在TTLCache中的函数的最大大小。
- ttl: 我们在’ttl’参数中给出的值表示函数缓存将在系统的缓存内存中存储多长时间。我们在ttl参数中给出的值以秒为单位。
现在,我们来使用这个TTLCache装饰器在Python程序中理解其工作原理和对我们的有用性。
示例2:
请查看以下程序以了解TTLCache函数的实现:
# Import cached and TTLCACHE from Cachetools Module
from cachetools import cached, TTLCache
# Import time module in the program
import time
# Using the TTLCache decorator
@cached(cache = TTLCache(maxsize = 64, ttl = 90))
# A default function to carry operations
def myFunc(num):
# Keeping track on total time taken
timeTaken = time.time()
time.sleep(num)
print("\nTotal time taken for executing the function: ", time.time() - timeTaken)
return (f"I am executed with the function number: {num}")
# Calling the default function twice
print(myFunc(4))
print(myFunc(4))
# Using sleep function to create a break
time.sleep(100)
# Calling function after break
print(myFunc(4))
输出:
Total time taken for executing the function: 4.015438556671143
I am executed with the function number: 4
I am executed with the function number: 4
Total time taken for executing the function: 4.015343904495239
I am executed with the function number: 4
说明:
在我们的程序中,我们从Cachetools模块导入了缓存和TTLCache装饰器,以及时间模块来计算调用函数所花费的时间。我们使用了TTLCache装饰器,通过定义以下参数来定义它的参数:maximize参数等于64,缓存存储的总时间等于90秒。在此之后,我们定义了一个默认函数来执行操作,然后我们使用time()函数来计算调用函数所花费的时间。然后,我们在print语句中调用了该函数两次。然后,我们使用sleep()函数在第三次调用函数时进行了一次休眠。我们使用了100秒的休眠时间,因为在TTLCache函数的参数中,我们给了90秒来存储缓存。
我们可以看到,在第二次调用函数时,它从TTLCache装饰器的缓存中调用了函数。但是当我们休眠后,它再次从程序中调用,因为TTLCache不再为函数存储缓存。
RRCache
RRCache是随机替换缓存(Random Replacement Cache)的缩写,顾名思义,RRCache是一种缓存技术的类型,其中函数从缓存内的项目中随机选择并丢弃它们。RRCache函数会在需要时随机执行此操作,以释放缓存内的一些空间。
语法: 使用RRCache装饰器函数的语法如下所示:
# Working on cache
@cached(cache = RRCache(maxsize = 34))
# Default function
def anyFunct():
pass # logical code in the function
参数: RRCache有一个必需参数,即maxsize,它与我们在TTLCache装饰器函数中使用的maxsize参数相同。除此之外,RRCache还接受一个可选的’choice参数’,默认在程序中设置为”random.choice”。
现在,让我们在Python程序中使用这个RRCache装饰器,以了解它的工作原理和对我们的用处。
示例3: 请查看以下程序,以了解RRCache函数的实现:
# Import cached and RRCACHE from Cachetools Module
from cachetools import cached, RRCache
# Import time module in the program
import time
# Using the RRCache decorator
@cached(cache = TTLCache(maxsize = 32))
# A default function to carry operations
def newFunc(m):
# Keeping track on total time taken
timeTaken = time.time()
time.sleep(m) # Delay in printing result displays task is under process
print("\nTotal time taken for executing the function: ", time.time() - timeTaken)
return (f"I am executed with the function number: {m}")
# Calling the default function in print statement
print(newFunc(2))
print(newFunc(3))
print(newFunc(1))
print(newFunc(2))
print(newFunc(2))
print(newFunc(4))
print(newFunc(3))
print(newFunc(3))
print(newFunc(2))
输出:
Total time taken for executing the function: 2.01472806930542
I am executed with the function number: 2
Total time taken for executing the function: 3.01532244682312
I am executed with the function number: 3
Total time taken for executing the function: 1.015653133392334
I am executed with the function number: 1
I am executed with the function number: 2
I am executed with the function number: 2
Total time taken for executing the function: 4.003695011138916
I am executed with the function number: 4
I am executed with the function number: 3
I am executed with the function number: 3
I am executed with the function number: 2
解释:
在输出中,我们可以看到RRCache装饰器的行为和功能,它在任何调用函数时都会随机丢弃缓存,并且很多次函数都是从存储在RRCache中的缓存内存中调用的。
LRUCache
LRUCache装饰器函数和我们学习的其他两个函数一样,被用在cached装饰器中。LRUCache代表最近最少使用缓存,正如其名称所示,该装饰器函数会将最近使用的函数保留在程序中的缓存中。
语法: 以下是在Python程序中使用LRUCache装饰器函数的语法:
# Working on cache
@cached(cache = LRUCache(maxsize = 4))
# Cache stored for this Default function
def anyFunc():
pass # some logical code will be written here
参数: LRUCache装饰器只接受一个参数,即maxsize,设置存储在缓存中的最近调用函数的数量。
现在,让我们在Python程序中使用这个LRUCache装饰器来理解它的工作原理以及它对我们的有用性。
示例4:
请查看以下程序,了解LRUCache函数的实现:
# Import cached and LRUCACHE from Cachetools Module
from cachetools import cached, LRUCache
# Import time module in the program
import time
# Using the LRUCache decorator function
@cached(cache = LRUCache(maxsize = 5))
# A default function to carry operations
def newFunc(m):
# Keeping track on total time taken
timeTaken = time.time()
time.sleep(m) # Delay in printing result displays task is under process
print("\nTotal time taken for calling the default function: ", time.time() - timeTaken)
return (f"I am executed with the function number: {m}")
# Calling the default function in print statement
print(newFunc(2))
print(newFunc(3))
print(newFunc(1))
print(newFunc(2))
print(newFunc(2))
print(newFunc(4))
print(newFunc(3))
输出:
Total time taken for calling the default function: 2.0151138305664062
I am executed with the function number: 2
Total time taken for calling the default function: 3.015472888946533
I am executed with the function number: 3
Total time taken for calling the default function: 1.0000226497650146
I am executed with the function number: 1
I am executed with the function number: 2
I am executed with the function number: 2
Total time taken for calling the default function: 4.015437841415405
I am executed with the function number: 4
I am executed with the function number: 3
说明:
我们调用了默认函数的次数比我们为LRUCache函数定义的maxsize参数多2倍,即7次。这是因为,首先,当函数被调用时,它被存储在LRUCache的缓存内存中,然后,在接下来的5次调用中,函数将从LRUCache修饰器中的缓存中调用。但是,第7次,由于现在超过了我们为LRUCache定义的maxsize值5,将从程序的内存中调用默认函数。
我们可以通过LRUCache修饰器导致结果变化的可视化。
LFUCache
LFUCache是另一种缓存技术,它代表最不经常使用的缓存(Least Frequently Used Cache),它也被称为缓存装饰器内部。LFUCache缓存技术用于检索在程序中项或函数被调用的频率(频繁)。在LFUCache缓存技术中,程序中最少频繁调用的项或函数将从缓存内存中丢弃,此操作用于释放缓存中的一些空间。
语法:
以下是在Python程序中使用LFUCache装饰器函数的语法:
# Working on cache
@cached(cache = LFUCache(maxsize = 5))
# Cache stored for this Default function
def newFunc():
pass # some logical code will be written here
参数: LFUCache 装饰器函数只接受一个参数,即 maxsize,它设置了缓存中将存储多少个最不经常被调用的函数。如果一个项目或函数参数在连续 maxsize 次数内没有被调用,则它将从缓存中被丢弃。
现在,让我们在Python程序中使用这个 LFUCache 装饰器来理解它的工作原理以及它对我们的用处。
示例5:
请看以下程序,了解 LFUCache 函数的实现:
# Import cached and LFUCACHE from Cachetools Module
from cachetools import cached, LFUCache
# Import time module in the program
import time
# Using the LFUCache decorator function
@cached(cache = LFUCache(maxsize = 5))
# A default function to carry operations
def newFunct(anyNum):
# Keeping track on total time taken
totalTime = time.time()
time.sleep(anyNum) # Delay in printing result displays task is under process
print("\nTotal time taken for calling the default function: ", time.time() - totalTime)
return (f"I am executed with the function number: {anyNum}")
# Calling the default function in print statement with number parameters
print(newFunct(2))
print(newFunct(3))
print(newFunct(1))
print(newFunct(2))
print(newFunct(2))
print(newFunct(4))
print(newFunct(1))
print(newFunct(3))
print(newFunct(3))
print(newFunct(2))
输出:
Total time taken for calling the default function: 2.01556396484375
I am executed with the function number: 2
Total time taken for calling the default function: 3.00508451461792
I am executed with the function number: 3
Total time taken for calling the default function: 1.0156123638153076
I am executed with the function number: 1
I am executed with the function number: 2
I am executed with the function number: 2
Total time taken for calling the default function: 4.0026326179504395
I am executed with the function number: 4
I am executed with the function number: 1
I am executed with the function number: 3
I am executed with the function number: 3
I am executed with the function number: 2
说明:
我们使用参数3调用了默认函数,然后连续5次没有再调用它(这与LFUCache函数中的maxsize参数相等)。因此,LFUCache将会从缓存中丢弃具有参数3的默认函数,并且会再次从程序的内存中调用它。
我们可以通过LFUCache装饰器产生的结果变化进行可视化。
结论
在这里,我们完成了Cachetools模块的教程,并且学习了Cachetools模块中的所有五个函数。我们学习了Cachetools模块函数在Python程序中的工作原理,以及如何使用它们来处理程序的缓存内存。