Python Cachetools 模块

2025年3月17日 | 阅读13分钟

我们大多数人可能都听说过“缓存”这个词,但并非所有人都了解它。在计算机技术中,缓存是一个软件或硬件组件,用于存储用户在计算机上执行的活动数据。当将来对相同数据发出请求时,它非常有用,因为那时相同的数据会更快地提供。系统中缓存组件中存储的数据可能是由于之前执行的计算,或者是相同数据副本存储在其他地方。因此,我们可以看到缓存对于更快的计算和在更短时间内获得更好的结果是多么重要。与数据的实际大小相比,缓存占用的空间很小,因此对用户来说它变得更有用。

Python 为我们提供了各种模块,通过这些模块我们可以处理系统中存在的缓存内存。Python 还为我们提供了模块,我们可以使用缓存内存进行更快的计算并节省时间。其中一个 Python 模块是 Python 中的 Cachetools 模块,我们将在本教程中学习这个模块。我们将简要详细了解 Cachetools 模块及其在 Python 中的功能,以及这些功能如何通过系统中存在的缓存帮助执行各种任务。

Python 中的 Cachetools 模块

Cachetools 模块:简介

Cachetools 是一个 Python 模块,它为我们提供了各种装饰器(该模块中可用的函数)和记忆化集合。Cachetools 帮助我们有效地处理系统中存在的缓存,我们可以使用 Cachetools 模块来更快地处理 Python 程序。Cachetools 模块还包括 Functools 模块(另一个 Python 模块)的 @lru_cache 装饰器函数的一些变体。

Cachetools 模块:安装

Cachetools 模块不是 Python 的内置模块,因此如果我们要使用此模块及其功能,我们必须先安装此模块。在本节中,我们将通过命令提示符终端使用 pip 安装程序安装 Cachetools 模块。首先,我们必须打开命令提示符终端,然后我们必须在终端内编写以下 pip 命令


Python Cachetools Module

当我们按下 Enter 键时,pip 安装程序将开始通过终端在我们的系统中安装 Cachetools 模块。

Python Cachetools Module

正如我们所看到的,Cachetools 模块已成功安装到我们的系统中,现在我们可以在 Python 程序中调用此模块,通过 Python 处理系统中存在的缓存。

Cachetools 模块:函数

在这里,我们只讨论 Python 的 Cachetools 模块中存在的函数。我们应该注意,这些函数是 Python 中的装饰器函数类型,当我们使用这些函数时,它们将在程序中用作装饰器函数。

以下是 Python 的 Cachetools 模块中存在的五个函数

  • cached
  • TTLCache
  • RRCache
  • LRUCache
  • LFUCache

现在,我们将详细研究上面提到的所有函数,并通过在 Python 程序中使用它们来理解它们的工作原理。

Cached 函数

Cachetools 模块的 cached 函数在 Python 中用作装饰器函数,它默认在程序中执行一个简单的缓存。当我们使用 cached 装饰器调用函数时,它会将我们调用的函数缓存起来,以便以后像缓存一样使用。

语法

以下是在 Python 程序中使用 cached 装饰器函数的语法

参数: 在 cached 装饰器中,我们使用一个名为 any_funct() 的默认函数(我们甚至可以在函数内部传递参数)。在使用 cached 装饰器时,我们将在默认函数内部编写逻辑代码,而不是 pass 语句。

现在,让我们在 Python 程序中使用这个 cached 装饰器,以便更好地理解它的工作原理以及它如何节省我们的时间。

示例 1

请看下面的程序,了解 cached 装饰器的实现

输出

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() 函数,其中包含相同的逻辑。现在,我们再次使用 time 函数来计算调用函数所需的总时间。然后,在 fiban() 函数中给出参数后,我们打印了操作以及使用 cached 装饰器执行操作所花费的总时间。

我们可以从输出中看到,当我们不使用 cached 调用函数时,它比使用 cached 装饰器调用函数时花费的时间要长得多(当两个函数相同,具有完全相同的逻辑并在调用时具有相同的参数时)。这就是 cached 装饰器通过将函数保存在缓存内存中,并在再次调用时节省大量时间的方式。

TTLCache 函数

TTLCache 也称为“存活时间”缓存,它也是 Cachetools 模块包中包含的装饰器函数。它也在我们程序中调用函数时处理系统中存在的缓存。但它与 Cachetools 模块的前一个函数的工作方式非常不同,我们可以在两个函数的语法中看到这一点。

语法

以下是在 Python 程序中使用 TTLCache 装饰器函数的语法

参数: 与 Cached 装饰器语法不同,我们必须在 TTLCache 装饰器函数中给出总共两个参数。我们还可以看到,在函数中使用参数之前,我们已将缓存类型指定为 TTLCache。以下是我们必须在 TTLCache 装饰器中使用的参数

  1. maxsize: TTLCache 函数中使用的 maxsize 定义了可以存储在 TTLCache 中的函数的最大大小。
  2. ttl: 我们在 'ttl' 参数中给出的值表示函数缓存将在系统缓存内存中存储多长时间。我们在 ttl 参数中给出的值以秒为单位。

现在,让我们在 Python 程序中使用这个 TTLCache 装饰器,以便理解它的工作原理以及它对我们有什么用处。

示例 2

请看下面的程序,了解 TTLCache 函数的实现

输出

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 模块导入了 cached 和 TTLCache 装饰器,以及 Time 模块,以便计算调用函数所需的时间。我们通过将 TTLCache 装饰器的参数定义如下:将 maximize 参数定义为 64,将缓存存储的总时间定义为 90 秒。之后,我们定义了一个默认函数来执行操作,然后我们使用了 time() 函数来计算调用函数所需的时间。之后,我们在 print 语句中调用了函数两次。然后,我们使用 sleep() 函数在第三次调用函数时暂停。我们使用了 100 秒的暂停,因为在 TTLCache 函数的参数中,我们给出了 90 秒来存储缓存。

我们可以从输出中看到,当我们在第二次调用函数时,它是从 TTLCache 装饰器的缓存内存中调用的。但是当我们暂停时,它又从程序中调用,因为 TTLCache 不再为函数存储缓存内存。

RRCache

RRCache 是 Random Replacement Cache 的缩写,顾名思义,RRCache 是一种缓存技术类型,其中函数从缓存内存中随机选择项目并将其丢弃。RRCache 函数会随机执行此操作,以便在需要时释放缓存内存中的一些空间。

语法: 以下是在 Python 程序中使用 RRCache 装饰器函数的语法

参数: RRCache 有一个必需参数,即 maxsize,它与我们在 TTLCache 装饰器函数中使用的 maxsize 参数相同。除了这个参数,RRCache 还接受一个可选的 'choice 参数',该参数在程序中默认设置为 "random.choice"。

现在,让我们在 Python 程序中使用这个 RRCache 装饰器,以便理解它的工作原理以及它对我们有什么用处。

示例 3: 请看下面的程序,了解 RRCache 函数的实现

输出

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 代表最近最少使用缓存(Least Recently Used Cache),顾名思义,这个装饰器函数会为程序中最近使用的函数保留缓存。

语法: 以下是在 Python 程序中使用 LRUCache 装饰器函数的语法

参数: LRUCache 装饰器只接受一个参数,即 maxsize,它设置了将有多少最近调用的函数存储在缓存中。

现在,让我们在 Python 程序中使用这个 LRUCache 装饰器,以便理解它的工作原理以及它对我们有什么用处。

示例 4

请看下面的程序,了解 LRUCache 函数的实现

输出

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),它也包含在 cached 装饰器中。LFUCache 缓存技术用于检索程序中调用项目或函数的频率(次数)。在 LFUCache 缓存技术中,程序中调用频率最低的项目或函数将从缓存内存中丢弃,执行此操作是为了释放缓存中的一些空间。

语法: 以下是在 Python 程序中使用 LFUCache 装饰器函数的语法

参数: LFUCache 装饰器函数只接受一个参数,即 maxsize,它设置了将有多少最不常用调用的函数存储在缓存中。如果一个项目或函数参数在 maxsize 连续次数内未被调用,那么它将从缓存中丢弃。

现在,让我们在 Python 程序中使用这个 LFUCache 装饰器,以便理解它的工作原理以及它对我们有什么用处。

示例 5

请看下面的程序,了解 LFUCache 函数的实现

输出

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 程序中工作,以及我们如何使用它们来处理程序的缓存内存。