文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Python中缓存lru_cache的方法是什么

2023-06-29 00:47

关注

这篇文章主要讲解了“Python中缓存lru_cache的方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Python中缓存lru_cache的方法是什么”吧!

一、前言

我们经常谈论的缓存一词,更多的类似于将硬盘中的数据存放到内存中以至于提高读取速度,比如常说的redis,就经常用来做数据的缓存。
Python的缓存(lru_cache)是一种装饰在被执行的函数上,将其执行的结果缓存起来,当下次请求的时候,如果请求该函数的传参未变则直接返回缓存起来的结果而不再执行函数的一种缓存装饰器。

二、举例说明

现在我们先不使用缓存来写一个求两数之和的函数,并调用执行它两次:

def test(a, b):    print('开始计算a+b的值...')    return a + bprint('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_cachedef test(a, b):    print('开始计算a+b的值...')    return a + bprint(test(1, 2))print(test(1, 2))

执行结果

开始计算a+b的值...
1+2等于: 3
1+2等于: 3

可以看到test函数只被执行了一次,第二次的调用直接输出了结果,使用了缓存起来的值。

当我们使用递归求斐波拉契数列 (斐波那契数列指的是这样一个数列:0,1,1,2,3,5,8,它从第3项开始,每一项都等于前两项之和) 的时候,缓存对性能的提升就尤其明显了:

不使用缓存求第40项的斐波拉契数列

import datetimedef 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.004424

使用缓存求第40项的斐波拉契数列:

import datetimedef 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

两个差距是非常明显的,因为不使用缓存时,相当于要重复执行了很多的函数,而使用了lru_cache则把之前执行的函数结果已经缓存了起来,就不需要再次执行了。

三、lru_cache 用法

1.参数详解

查看lru_cache源码会发现它可以传递两个参数:maxsize、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) maxsize

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

2)typed

默认为false,代表不区分数据类型,如果设置为True,则会区分传参类型进行缓存,官方是这样描述的:

如果typed为True,则将分别缓存不同类型的参数,
例如,f(3.0)和f(3)将被视为具有明显的结果。

但在python3.9.8版本下进行测试,typed为false时,按照官方的测试方法测试得到的还是会被当成不同的结果处理,这个时候typed为false还是为true都会区别缓存,这与官方文档的描述存在差异:

from functools import lru_cache@lru_cachedef test(a):    print('函数被调用了...')    return aprint(test(1.0))print(test(1))

执行结果

函数被调用了...
1.0
函数被调用了...

但如果是多参数的情况下,则会被当成一个结果:

from functools import lru_cache@lru_cachedef test(a, b):    print('函数被调用了...')    return a , bprint(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 , bprint(test(1.0, 2.0))print(test(1, 2))

执行结果

函数被调用了...
(1.0, 2.0)
函数被调用了...
(1, 2)

当传参个数大于1时,才符合官方的说法,不清楚是不是官方举例有误

2. lru_cache不支持可变参数

当传递的参数是dict、list等的可变参数时,lru_cache是不支持的,会报错:

from functools import lru_cache@lru_cachedef test(a):    print('函数被执行了...')    return aprint(test({'a':1}))

报错结果

TypeError: unhashable type: 'dict'

四、lru_cache 与redis的区别

缓存缓存位置是否支持可变参数是否支持分布式是否支持过期时间设置支持的数据结构需单独安装
redis缓存在redis管理的内存中支持5种数据结构
lru_cache缓存在应用进程的内存中,应用被关闭则被清空字典(参数为:key,结果为:value)

感谢各位的阅读,以上就是“Python中缓存lru_cache的方法是什么”的内容了,经过本文的学习后,相信大家对Python中缓存lru_cache的方法是什么这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     801人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     348人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     311人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     432人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     220人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯