☰
Python中缓存lru_cache的基本介绍和讲解
2026/10/2 2:24:45 网站建设 项目流程

中缓存的基本介绍和讲解

更新时间已经更新到了二零二二年一月二十八日的十时三十四分二十三秒, 此时的作者是曲鸟。

缓存这种方式, 是把一些定量的数据给保存起来。这么做的目的是为了能够去迎合后续的那些请求情况。其主要的意图在于, 是想要加快对于数据的检索速度。在下面这篇文章当中, 主要给大家进行了介绍。这些是关于关于中缓存的,基本介绍和讲解的这些相关的一些资料。有需要的朋友, 是可以来进行参考查阅一下的。

一、前言

在很多时候, 咱们聊到的缓存这个东西, 其意思其实更接近于把存在硬盘里的那些数据给挪到内存里去存着, 为的就是能让读取的速度变得更快一点, 像是大家常常挂在嘴边的 redis , 就经常会被拿来用作是数据处理时候的一个缓存工具。

所谓的()缓存, 其实就是一种装饰器, 它被用在了正在被执行的函数之上, 主要作用就是把执行的结果缓存保存起来, 这样在下次有人发起请求的时候, 只要检查发现传入函数的参数没有发生变化, 就直接返回之前缓存好的结果, 完全不需要再去把那个函数重新执行一遍。

那么它与redis之间的具体差异究竟在哪里? 它又具备哪些独特的优势? 同时应如何正确地加以使用? 接下来将为你展开详细讲解。

二、举例说明

1.此时此刻咱们暂时不用缓存这个玩意儿, 去写一下计算两个数字相加结果的函数代码, 随后把这段代码拿来执行两次看看情况:

def test(a, b):

print('开始计算a+b的值...')

return a + b

print('1+2等于:', test(1, 2))

print('1+2等于:', test(1, 2))

执行结果

开始对a+b的数值进行计算工作。

1+2等于: 3

开始计算a+b的值...

1+2等于: 3

能够观察到 test 这个函数被执行了有两次这么个情况, 紧接着在此刻我们引入缓存这一机制, 然后接着往下继续进行执行操作。

from functools import lru_cache

@lru_cache

def test(a, b):

print('开始计算a+b的值...')

return a + b

print(test(1, 2))

print(test(1, 2))

执行结果

开始计算a+b的值...

1+2等于: 3

1+2等于: 3

我们可以看到这个叫做test的函数仅仅只执行了一次而已, 当进行第二次调用的时候, 它就直接将之前已经缓存好的那个结果给输出了出来, 所以说这是使用了被缓存起来的那个值。

2.当我们采用递归的方式来进行计算, 目的是获取斐波拉契数列的数值的时候, 引入缓存机制对于整体性能的改善效果就会变得特别突出和明显。

请求计算斐波拉契数列中排在前面的第四十个数据, 并且在这个过程里面不要依赖于任何形式的缓存机制。

import datetime

def fibonacci(num):

# 不使用缓存时,会重复执行函数

return num if num < 2 else fibonacci(num - 1) + fibonacci(num - 2)

start = datetime.datetime.now()

print(fibonacci(40))

end = datetime.datetime.now()

print('执行时间', end - start)

执行时间

执行的时间是0:00:29。

采取使用缓存的方法去求出斐波拉契数列中的第40项。

import datetime

def fibonacci(num):

# 不使用缓存时,会重复执行函数

return num if num < 2 else fibonacci(num - 1) + fibonacci(num - 2)

start = datetime.datetime.now()

print(fibonacci(40))

end = datetime.datetime.now()

print('执行时间', end - start)

执行时间

这个操作的执行所用时间是0:00:00。

这两个差别是非常明显的。因为在不使用缓存这一情况下, 相当于是重复执行非常多的函数。而在使用之后, 是把之前所执行的函数结果已经给缓存起来的, 这样的话, 就不需要进行再次执行了。

三、 用法是第1种, 具体的参数需要详细地解释。

去查看代码的源文件就会发现, 它能够传递两个参数, 第一个参数是、typed。

def lru_cache(maxsize=128, typed=False):

"""Least-recently-used cache decorator.

If *maxsize* is set to None, the LRU features are disabled and the cache

can grow without bound.

...

"""

1)

该参数代表被装饰的方法最大可缓存的结果数量, 当被装饰方法传参不同结果就不一样, 如果传参一样则结果为同一个结果, 不指定传参的时候默认值为128, 这表示最多缓存128个返回结果, 当已经达到了128个时, 如果有新的结果要保存, 则会删除最旧的那个结果, 如果传入为None则表示可以缓存无限个结果。

2)typed

这个配置的默认值是false, 代表着不区分数据类型。如果把它设置为True, 那么就会根据参数类型的不同来进行缓存了。关于这一点, 官方是这样描述的:

如果那个typed的值是表示为True的情况, 那么系统将会对不同类型的参数展开操作, 并且把每一个不同的类型分别存放到相应的缓存区域当中去。

举例来说, f(3.0)与f(3)这两项操作的结果存在显著差异。

当时我们是在点九点八这个版本里进行测试的, 当typed这个参数设成false的时候, 按照官方教我们的那种测法去跑一下, 结果发现它最后得到的反馈还是会认为这是两个不一样的情况在分别处理, 于是问题来了, 不管 typed 的值到底是 false 还是 true, 系统都会去区分缓存的内容, 这个现象跟官网上写的那个说明文档上的描述是有出入的。

from functools import lru_cache

@lru_cache

def test(a):

print('函数被调用了...')

return a

print(test(1.0))

print(test(1))

执行结果

函数被调用了...

1.0

函数被调用了...

但是, 如果存在多个参数的情形, 那么就会被视为一个统一的结果:

from functools import lru_cache

@lru_cache

def test(a, b):

print('函数被调用了...')

return a , b

print(test(1.0, 2.0))

print(test(1, 2))

执行结果

函数被调用了...

(1.0, 2.0)

(1.0, 2.0)

在这个时间点, 当你把typed这个参数设置成true的时候, 系统就会对缓存进行区分处理:

from functools import lru_cache

@lru_cache(typed=True)

def test(a, b):

print('函数被调用了...')

return a , b

print(test(1.0, 2.0))

print(test(1, 2))

执行结果

函数被调用了...

(1.0, 2.0)

函数被调用了...

(1, 2)

在传参的个数超过1个的情况下, 才算是符合官方说法的一种情况, 对于是否存在这种说法并不清楚, 有可能是官方给出的举例内容存在错误。

2. 不支持可变参数

当需要传递的参数类型为字典、列表这类可变的参数对象时, 当前是不支持的, 系统将会报错提示出错。

from functools import lru_cache

@lru_cache

def test(a):

print('函数被执行了...')

return a

print(test({'a':1}))

报错结果

: type: 'dict'

四、 与redis的区别, 缓存位置是否支持可变参数, 是否支持分布式, 是否支持过期时间设置, 支持的数据结构, 需不需要单独安装。

redis

数据是被存放到了由redis来负责管理的内存里面的。

支持5种数据结构

将数据缓存在当前正在运行的应用的内存空间里面, 一旦这个应用被手动关闭掉, 那么缓存里面的内容就随即被全部清空了。

字典是一个数据结构, 它包含键和值这两个参数, 其中键表示key, 而结果则对应value。

五、总结

依据上述的分析内容,该功能相比于Redis而言, 其结构是要简单许多许多的, 同时在操作使用的过程里会变得非常方便, 因此它非常适合被应用于那些规模比较小的单一单体应用项目之中。

可是要是所涉及到的缓存数据类型比较多, 并且用户想要对这些缓存数据进行更为细致的管理, 又或者业务场景里需要为缓存的内容配置一个失效到期的时间点(例如像是登录身份验证的token令牌这种情况), 那么在此类情况下, 选择使用Redis就是更优更好的一个方案。

到这里, 这篇关于中缓存的基本介绍和讲解的文章就介绍到这了。如果你还想知道更多相关的内容, 不妨去搜索一脚本之家以前的文章, 或者是继续浏览下面的这些相关文章。在这里, 我们衷心希望大家以后能够多多支持脚本之家!

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询