‘壹’ python requests 会缓存,吗
你好 python 并不会自动缓存数据, 极度怀疑你数据没插入成功,或者插入操作不在那个2秒SLEEP的时间里面。
‘贰’ python 缓存
详解: https://pythonav.com/wiki/detail/6/88/
一.
1.int 类型的缓存
[-5, 256]的整型,只要Python解释器一运行,这些数值就加载到了内存
2.free_list:float、list、touple、dict等都是这种方式
当一个对象引用计数为0时,按理说就应该被垃圾回收了,但是Python不是这么做的,而是将对象放入到free_list链表里面。这样,以后再去创建该对象时,不会重新开辟内存,而是直接使用free_list里面的
‘叁’ Python内存驻留机制
字符串驻留机制在许多面向对象编程语言中都支持,比如Java、python、Ruby、PHP等,它是一种数据缓存机制,对不可变数据类型使用同一个内存地址,有效的节省了空间,本文主要介绍Python的内存驻留机制。
字符串驻留就是每个字符串只有一个副本,多个对象共享该副本,驻留只针对不可变数据类型,比如字符串,布尔值,数字等。在这些固定数据类型处理中,使用驻留可以有效节省时间和空间,当然在驻留池中创建或者插入新的内容会消耗一定的时间。
下面举例介绍python中的驻留机制。
在Python对象及内存管理机制一文中介绍了python的参数传递以及以及内存管理机制,来看下面一段代码:
知道结果是什么吗?下面是执行结果:
l1和l2内容相同,却指向了不同的内存地址,l2和l3之间使用等号赋值,所以指向了同一个对象。因为列表是可变对象,每创建一个列表,都会重新分配内存,列表对象是没有“内存驻留”机制的。下面来看不可变数据类型的驻留机制。
在 Jupyter或者控制台交互环境 中执行下面代码:
执行结果:
可以发现a1和b1指向了不同的地址,a2和b2指向了相同的地址,这是为什么呢?
因为启动时,Python 将一个 -5~256 之间整数列表预加载(缓存)到内存中,我们在这个范围内创建一个整数对象时,python会自动引用缓存的对象,不会创建新的整数对象。
浮点型不支持:
如果上面的代码在非交互环境,也就是将代码作为python脚本运行的结果是什么呢?(运行环境为python3.7)
全为True,没有明确的限定临界值,都进行了驻留操作。这是因为使用不同的环境时,代码的优化方式不同。
在 Jupyter或者控制台交互环境 中:
满足标识符命名规范的字符:
结果:
乘法获取字符串(运行环境为python3.7)
结果:
在非交互环境中:
注意: 字符串是在编译时进行驻留 ,也就是说,如果字符串的值不能在编译时进行计算,将不会驻留。比如下面的例子:
在交互环境执行结果如下:
都指向不同的内存。
python 3.7 非交互环境执行结果:
发现d和e指向不同的内存,因为d和e不是在编译时计算的,而是在运行时计算的。前面的 a = 'aa'*50 是在编译时计算的。
除了上面介绍的python默认的驻留外,可以使用sys模块中的intern()函数来指定驻留内容
结果:
使用intern()后,都指向了相同的地址。
本文主要介绍了python的内存驻留,内存驻留是python优化的一种策略,注意不同运行环境下优化策略不一样,不同的python版本也不相同。注意字符串是在编译时进行驻留。
--THE END--
‘肆’ python有缓存模块吗
从Python 3.2开始,可以使用functools库中的装饰器@lru_cache。这是最近使用过的缓存,所以其中的项目没有到期时间,但作为快速入侵,它非常有用。
from functools import lru_cache
@lru_cache(maxsize=256)def f(x):
return x*xfor x in range(20):
print f(x)for x in range(20):
print f(x)
‘伍’ Python性能提升神器!lru_cache的介绍和讲解
我们经常谈论的缓存一词,更多的类似于将硬盘中的数据存放到内存中以至于提高读取速度,比如常说的redis,就经常用来做数据的缓存。 Python的缓存(lru_cache)是一种装饰在被执行的函数上,将其执行的结果缓存起来,当下次请求的时候,如果请求该函数的传参未变则直接返回缓存起来的结果而不再执行函数的一种缓存装饰器。
那它和redis的区别在哪?有什么优势?怎么使用? 下面为你讲解
1.现在我们先不使用缓存来写一个求两数之和的函数,并调用执行它两次:
执行结果
可以看到 test 被执行了两次,现在我们加上缓存再进行执行:
执行结果
可以看到 test 函数只被执行了一次,第二次的调用直接输出了结果,使用了缓存起来的值。
2.当我们使用递归求斐波拉契数列 (斐波那契数列指的是这样一个数列:0,1,1,2,3,5,8,它从第3项开始,每一项都等于前两项之和) 的时候,缓存对性能的提升就尤其明显了:
不使用缓存求第40项的斐波拉契数列
执行时间
使用缓存求第40项的斐波拉契数列:
执行时间
两个差距是非常明显的,因为不使用缓存时,相当于要重复执行了很多的函数,而使用了 lru_cache 则把之前执行的函数结果已经缓存了起来,就不需要再次执行了。
查看lru_cache源码会发现它可以传递两个参数: maxsize 、 typed :
代表被lru_cache装饰的方法最大可缓存的结果数量 (被装饰方法传参不同一样,则结果不一样;如果传参一样则为同一个结果) , 如果不指定传参则默认值为128,表示最多缓存128个返回结果,当达到了128个时,有新的结果要保存时,则会删除最旧的那个结果。如果maxsize传入为None则表示可以缓存无限个结果;
默认为false,代表不区分数据类型,如果设置为True,则会区分传参类型进行缓存,官方是这样描述的:
但在python3.9.8版本下进行测试,typed为false时,按照官方的测试方法测试得到的还是会被当成不同的结果处理,这个时候typed为false还是为true都会区别缓存,这与官方文档的描述存在差异:
执行结果
但如果是多参数的情况下,则会被当成一个结果:
执行结果
这个时候设置typed为true时,则会区别缓存:
执行结果
当传参个数大于1时,才符合官方的说法,不清楚是不是官方举例有误
当传递的参数是dict、list等的可变参数时,lru_cache是不支持的,会报错:
报错结果
缓存 缓存位置 是否支持可变参数 是否支持分布式 是否支持过期时间设置 支持的数据结构 需单独安装 redis 缓存在redis管理的内存中 是 是 是 支持5种数据结构 是 lru_cache 缓存在应用进程的内存中,应用被关闭则被清空 否 否 否 字典(参数为:key,结果为:value) 否
经过上面的分析,lru_cache 功能相对于redis来说要简单许多,但使用起来更加方便,适用于小型的单体应用。如果涉及的缓存的数据种类比较多并且想更好的管理缓存、或者需要缓存数据有过期时间(类似登录验证的token)等,使用redis是优于lru_cache的。
‘陆’ python3_原生 LRU 缓存
原生 LRU 缓存(最低 Python 版本为 3.2)
目前,几乎所有层面上的软件和硬件中都需要缓存。Python 3 将 LRU(最近最少使用算法)缓存作为一个名为“lru_cache”的装饰器,使得对缓存的使用非常简单。
下面是一个简单的斐波那契函数,我们知道使用缓存将有助于该函数的计算,因为它会通过递归多次执行相同的工作。
现在,我们可以使用“lru_cache”来优化它(这种优化技术被称为“memoization”)。通过这种优化,我们将执行时间从几十秒降低到了几秒。
‘柒’ 如何给轻量python程序,脚本制作缓存
1, 首先下载并安装Python 2.7 2, 写一个简单地Python源文件,比如test.py,内容如下: import sys, os def test(arg1, arg2): print "begin test..." fun1('1', '2') print arg1 print arg2 def fun1(arg1, arg2): print arg1 print arg2 if __name...
‘捌’ 如何在python中使用时间限制进行缓存
可以试试装饰器
defcache(fn=None,time_to_live=3600*24):#oneDAYdefault(orwhatever)
ifnotfn:returnfunctools.partial(cache,time_to_live=time_to_live)
my_cache={}
def_inner_fn(*args,**kwargs)
kws=sorted(kwargs.items())#inpython3.6+youdontneedsorted
key=tuple(args)+tuple(kw)
ifkeynotinmy_cacheortime.time()>my_cache[key]['expires']:
my_cache[key]={"value":fn(*args,**kwargs),"expires":time.time()+time_to_live}
returnmy_cache[key]
return__inner_fn
@cache(time_to_live=3600)#anhour
defmy_sqrt(x):
returnx**0.5@cache(time_to_live=60*30)#30mins
defget_new_emails():
returnmy_stmp.get_email_count()
‘玖’ python 如何释放缓存
我觉得可能是因为你的py文件在第一次启动后,已经编译成pyc文件了,再次启动的时候都是加载pyc,省去了编译的阶段,所以速度很快。
你可以试着把程序目录下的所有pyc或者你的代码文件对应的pyc文件删除,看看是不是可以和第一次加载速度相同
‘拾’ 一道Python的题目:实现一个简易的写缓存机制。要怎么写是哪方面的知识要去看什么内容
#-*-coding:utf-8-*-
__author__='lpe234'
__date__='2015-04-30'
classMemCache(object):
def__init__(self,limit=3):
self.limit=limit
self.store=[]
defput(self,param=None):
self.store.append(param)
iflen(self.store)>=self.limit:
self._write_db(self.store[:self.limit])
self.store=self.store[self.limit:]
def_write_db(self,param=None):
print'writetodb{0}'.format(param)
if__name__=='__main__':
mem=MemCache(limit=7)
user_input=range(20)
forxinuser_input:
mem.put(x)
C:Python27python.exeD:/00/gui/tmp.py
writetodb[0,1,2,3,4,5,6]
writetodb[7,8,9,10,11,12,13]
Processfinishedwithexitcode0