0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Python 中怎么来实现类似 Cache 的功能

科技绿洲 来源:Python实用宝典 作者:Python实用宝典 2023-10-17 10:47 次阅读

cachetools,这是一个可扩展的基于内存的 Collections、Decorators 的封装实现。

因为是 Cache,那么就一定有它的页面置换算法。根据操作系统学过的一些知识,置换算法就会有 LRU、LFU、FIFO 等等。比如说,当 Cache 已经满了的情况下,如果这时候再插入一个新的数据,那么这时候就需要根据页面置换算法对已有的数据进行置换,用新的数据替代旧的数据,保证 Cache 最大占用量不会超标。

废话不多说了,这里我们来体验下这个库的具体用法吧。

首先是安装,直接使用 pip3 安装即可:

pip3 install cachetools

安装好之后,我们再来看看它的具体用法。

基本 Cache 的使用

我们来看一个简单的实例:

from cachetools import Cache

cache = Cache(maxsize=3)
cache['1'] = 'Hello'
cache['2'] = 'World'
print('current size', cache.currsize)
cache.pop('2')
print(cache.items)
print('length', len(cache))
cache['3'] = 'Hello'
cache['4'] = 'World'
print('current size', cache.currsize)
cache['5'] = 'Hello'
print('current size', cache.currsize)
print(cache.items)

运行结果如下:

current size 2
 bound method Mapping.items of Cache([('1', 'Hello')], maxsize=3, currsize=1) >
length 1
current size 3
current size 3
 bound method Mapping.items of Cache([('3', 'Hello'), ('4', 'World'), ('5', 'Hello')], maxsize=3, currsize=3) >

首先这里声明了一个 Cache 对象,有一个必传的参数是 maxsize,这里设置为 3,这里的 3 其实就是长度的意思,并不是实际内存占用大小。

接着我们赋值了 1 和 2 两个键名,接着打印出来了当前 Cache 的大小,所以结果就是 2,这个 size 就是一个单纯的数量值。

然后接着调用了 pop 方法移除了 2 对应的内容,然后打印 Cache 的所有内容和对应长度,理所应当,长度就是 2,然后就剩下一个值。

接着我们又赋值了 3 和 4 两个键名,然后打印了当前 Cache 的大小,这会 Cache 达到了 maxsize,结果就是 3。

最后我们又赋值了 5 这个键名,然后打印了当前 Cache 的大小和 Cache 的所有内容,因为 Cache 已经达到了 maxsize 了,所以结果依然是 3,最前面的 1 这个键名对应的内容就被移除了。

所以,这个 Cache 对象可以维持一个最大恒定大小,并且保证长度不会超过 maxsize。

其他 Cache 的使用

当然除了 Cache,还有一些 Cache 的子类,比如说 FIFOCache、LFUCahce、LRUCache、MRUCache、RRCache,这里简单说下:

  • FIFO:First In、First Out,就是先进先出。
  • LFU:Least Frequently Used,就是淘汰最不常用的。
  • LRU:Least Recently Used,就是淘汰最久不用的。
  • MRU:Most Recently Used,与 LRU 相反,淘汰最近用的。
  • RR:Random Replacement,就是随机替换。

具体的实例这里就不再讲解了。

特殊 TTLCache 的使用

当然除了基本的 Cache,cachetools 还提供了一种特殊的 Cache 实现,叫做 TTLCache。

TTL 就是 time-to-live 的简称,也就是说,Cache 中的每个元素都是有过期时间的,如果超过了这个时间,那这个元素就会被自动销毁。如果都没过期并且 Cache 已经满了的话,那就会采用 LRU 置换算法来替换掉最久不用的,以此来保证数量。

下面我们来看一个样例:

from datetime import timedelta, datetime
from cachetools import TTLCache
from time import sleep

cache = TTLCache(maxsize=3, ttl=timedelta(seconds=5), timer=datetime.now)
cache['1'] = 'Hello'
sleep(1)
cache['2'] = 'World'
print(cache.items)
sleep(4.5)
print(cache.items)
sleep(1)
print(cache.items)

运行结果如下:


这里我们声明了一个 TTLCache,maxsize 是 3,然后 ttl 设置为了 5 秒,也就是说,每个元素 5 秒之后都会过期。

首先我们赋值 1 这个键名为 Hello,然后 1 秒之后赋值 2 这个键名为 World,接着将现有 Cache 的结果输出出来。

接着等待 4.5 秒,这时候 1 这个键名就已经超过 5 秒了,所以 1 这个键名理应就被销毁了。

接着再等待 1 秒,这时候 2 这个键名也超过 5 秒了,所以 2 这个键名也理应就被销毁了。

最后看运行结果也如我们期望的一样。

大小计算

有的同学说,你这里 maxsize 用的这个数字指的是内容的长度,但实际上不同的内容占用的空间是完全不一样的,有没有根据实际内存占用来计算 size 的方法呢?

有的!

这里我们只需要替换掉 Cache 的 getsizeof 方法即可。

这里我们需要额外引入一个库,叫做 pympler,它提供了一个 asizeof 方法可以计算实际 Object 的占用内存大小,单位是 bytes。

pympler 安装:

pip3 install pympler

所以,如果我们要设置 Cache 占用的最大内存大小,比如 2MB,那就可以这么设置:

from cachetools import Cache
from pympler import asizeof

cache = Cache(maxsize=2 * 1024 * 1024, getsizeof=asizeof.asizeof)
cache['a'] = '123'
print(cache.currsize)
cache['b'] = '123'
print(cache.currsize)
cache['c'] = '456'
print(cache.currsize)
cache['d'] = {
    'a': 'b',
    'b': 'c',
    'c': 'd'
}
print(cache.currsize)

这里 maxsize 我们就设置为了 2MB,同时 getsizeof 方法设置为了 pympler 的 asizeof 方法,这样 Cache 在计算 size 的时候就会用 asizeof 方法了。

这里我们随便插入一些数据,看看实际的 size 变化,运行结果如下:

56
112
168
640

其结果就是 Cache 占用的字节数。可以看到数据的复杂度高,占用的空间越大。

更多

好了,其实到现在为止,基本的 Cache 和 TTLCache 就够我们使用了。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 封装
    +关注

    关注

    126

    文章

    7767

    浏览量

    142698
  • 内存
    +关注

    关注

    8

    文章

    2996

    浏览量

    73867
  • 操作系统
    +关注

    关注

    37

    文章

    6727

    浏览量

    123181
  • Cache
    +关注

    关注

    0

    文章

    129

    浏览量

    28294
  • python
    +关注

    关注

    55

    文章

    4778

    浏览量

    84439
收藏 人收藏

    评论

    相关推荐

    labview怎么实现类似PPT的超链接功能啊?

    labview怎么实现类似PPT的超链接功能啊?就是在主VI调用子VI后显示子VI的界面,
    发表于 10-21 21:04

    5种Python实现方式详解

    CPython扩展的用户来说,极力推荐Jython。IronPythonIronPython与Jython类似,所不同的是IronPython在CLR上实现Python,即面向.NET平台,由C#编写
    发表于 05-22 15:52

    请问Python如何实现vlookup函数的功能

    vlookup函数功能非常强大,那在Python如何实现
    发表于 11-06 06:11

    Python解释器的基本结构

    供足够的上下文进一步研究它。我们的目标并不是解释所有关于解释器的知识——就像编程和计算机科学许多有趣的领域一样,您可以花费数年时间深入理解这个主题。Byterun它的结构类似
    发表于 09-16 06:42

    CacheTag电路的设计

    摘要:在SoC系统,片上缓存(Cache)的采用是解决片上处理器和片外存储器之间速度差异的重要方法,Cache中用来存储标记位并判断Cache是否命中的Tag电路的设计将会影响到整个
    发表于 05-08 09:26 11次下载

    Python语言在人工智能功能及优势

    其他语言制作的各种模块轻松地联结在一起。本文主要详解Python语言在人工智能功能及优势,具体的跟随小编详细的了解一下。
    发表于 05-22 14:29 1.2w次阅读

    cache结构与工作原理

    更详细的讲,cache的结构其实和内存的结构类似,也包含地址和内容,只是cache的内容除了存的数据(data)之外,还包含存的数据的物理内存的地址信息(tag),因为CPU发出的寻址信息都是针对
    发表于 06-03 14:24 1.2w次阅读
    <b class='flag-5'>cache</b>结构与工作原理

    jsonpath库的常规功能介绍

    Python我们可以使用jsonpath这个库实现JSONPath的功能。 2 在Python
    的头像 发表于 09-01 14:11 2041次阅读
    jsonpath库<b class='flag-5'>中</b>的常规<b class='flag-5'>功能</b>介绍

    Buffer与cache的区别

    Bbuffer 与 Cache 非常类似,因为它们都用于存储数据数据,被应用层读取字节数据。
    的头像 发表于 07-01 10:44 3789次阅读

    抽样在Python是如何实现

    今天和大家聊聊抽样的几种常用方法,以及在Python是如何实现的。
    的头像 发表于 08-05 10:59 1164次阅读

    如何用Python实现文件系统的操作功能

    就来介绍一下如何用 Python 实现这些功能 输出当前的路径 我们可以通过 Python 当中的 OS 库
    的头像 发表于 10-30 14:27 379次阅读
    如何用<b class='flag-5'>Python</b><b class='flag-5'>来</b><b class='flag-5'>实现</b>文件系统的操作<b class='flag-5'>功能</b>

    Cache内容锁定是什么

    “锁定”在cache的块在常规的cache替换操作不会被替换,但当通过C7控制cache
    的头像 发表于 10-31 11:31 714次阅读

    怎么在Python实现截图功能

    操作。 今天Python实用宝典就来讲讲怎么在Python实现截图功能,以下教程默认您已经安装好了Py
    的头像 发表于 11-03 15:32 903次阅读
    怎么在<b class='flag-5'>Python</b><b class='flag-5'>中</b><b class='flag-5'>实现</b>截图<b class='flag-5'>功能</b>

    C++实现类似instanceof的方法

    函数,可实际上C++没有。但是别着急,其实C++中有两种简单的方法可以实现类似Java的instanceof的功能。 在 C++
    的头像 发表于 07-18 10:16 528次阅读
    C++<b class='flag-5'>中</b><b class='flag-5'>实现</b><b class='flag-5'>类似</b>instanceof的方法

    如何实现Python复制文件操作

    Python 中有许多“开盖即食”的模块(比如 os,subprocess 和 shutil)以支持文件 I/O 操作。在这篇文章,你将会看到一些用 Python 实现文件复制的特殊
    的头像 发表于 07-18 14:53 362次阅读