【Python】如何实现Cche的功能(详细教学)

news/2024/7/24 3:12:12 标签: python, 数据分析, pandas

文章目录

  • 介绍
  • 一、pandas是什么?
  • 二、基本 Cache 的使用
    • 1.引入库
  • 二,其他 Cache 的使用
  • 三,特殊 TTLCache 的使用
  • 四,大小计算
  • 总结

—近期要实现一个小的功能:我需要在短期内对某些数据进行快速查询、修改等操作,但这些数据仅仅在短期内会用到,过一小段时间就可以销毁了。
所以,为了提高数据的操作效率,放在内存中无疑是非常合适的,但是内存总是有限的,总不能无限地放吧,内存溢出了咋办?

所以,有没有一种自动回收机制,可以过一小段时间自动将旧的数据进行移除或替换呢?

仔细一想,这不就相当于一个 Cache 吗?既能在短期内实现快速查询、修改等操作,等不用了就被自动置换掉。

是的,没错,那在 Python 中有没有类似实现呢?

有的,叫做 cachetools,这里我们就来简单介绍下它的用法。

介绍

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

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

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

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

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


提示:以下是本篇文章正文内容,下面案例可供参考

pandas_33">一、pandas是什么?

示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。

二、基本 Cache 的使用

1.引入库

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

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 置换算法来替换掉最久不用的,以此来保证数量。

下面我们来看一个样例:

python">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)

运行结果如下:

<bound method Mapping.items of TTLCache([('1', 'Hello'), ('2', 'World')], maxsize=3, currsize=2)>
<bound method Mapping.items of TTLCache([('2', 'World')], maxsize=3, currsize=1)>
<bound method Mapping.items of TTLCache([], maxsize=3, currsize=0)>

这里我们声明了一个 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,那就可以这么设置:

python">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 就够我们使用了。

另外 cachetools 还提供了一些装饰器,可以帮助我们更方便地使用 Cache,更多内容可以看官方文档:https://cachetools.readthedocs.io/en/stable/。


http://www.niftyadmin.cn/n/179536.html

相关文章

玩转肺癌目标检测数据集Lung-PET-CT-Dx ——②预览数据集,绘制锚框

文章目录数据集预览CT图片和xml文件的对应关系查看dcm文件信息将dcm图像与xml标注文件配对本文接着预览数据集的概况&#xff0c;看看图像文件和标注文件该如何处理。 本文所用代码&#xff1a; 我的Github 数据集预览 数据集分成三部分&#xff1a; Images 为我们需要下载的…

【算法题】2466. 统计构造好字符串的方案数

题目&#xff1a; 给你整数 zero &#xff0c;one &#xff0c;low 和 high &#xff0c;我们从空字符串开始构造一个字符串&#xff0c;每一步执行下面操作中的一种&#xff1a; 将 ‘0’ 在字符串末尾添加 zero 次。 将 ‘1’ 在字符串末尾添加 one 次。 以上操作可以执行任…

【K8S系列】深入解析 ReplicaSet

目录 序言 1 基础介绍 1.1 重要特性 1.2 控制器 1.3 标签选择器 示例配置文件&#xff1a; 1.4 自动伸缩 示例配置文件&#xff1a; 2 拓展 2.1 Deployment 水平扩展 思考问题&#xff1a; 3 投票 序言 要从容地着手去做一件事&#xff0c;但一旦开始&#xff0c;…

线程的生命周期

从操作系统的角度理解&#xff1a; 线程是在调用start方法之后&#xff0c;它才变成就绪状态&#xff0c;在就绪状态下&#xff0c;线程开始去抢夺CPU的执行权&#xff0c;它是正在抢&#xff0c;但是还没有抢到&#xff0c;没有抢到就无法执行代码。所以就绪状态它是有执行资…

Git-分布式版本控制工具

目录 Git的简单介绍 软件基本理论/原理的介绍 软件的下载、安装、配置 软件实际应用案例 Git的简单介绍 版本控制概念 正如文章标题所写&#xff0c;git是一个分布式版本控制工具。 什么是版本控制呢&#xff1f; 下面给出一个场景&#xff1a;老板让你写一个方案&…

C++————构造函数与析构函数

在C中&#xff0c;我们有一个专门有一个函数给类的成员赋值&#xff0c;这个赋初值的工作由构造函数来完成。 说明&#xff1a; 1.构造函数的名字必须与类名相同&#xff0c;否则编译程序将把它当成一般的成员函数来处理。 2.构造函数没有返回值&#xff0c;在定义构造函数时&a…

文章生成器-免费的文章生成器

随着信息爆炸的时代&#xff0c;自媒体人员不仅需要创造性的策略&#xff0c;还需要快速产生具有高质量文章的能力&#xff0c;这样才能快速响应趋势并保持优势。文章生成器&#xff0c;一款基于人工智能和自然语言处理技术的文本生成软件&#xff0c;可在没有任何人工干预的情…

蓝桥杯算法心得——小明的彩灯(差分)

大家好&#xff0c;我是晴天学长&#xff0c;今天的题目类型是前缀和的亲戚&#xff08;差分&#xff09;&#xff0c;两个互逆&#xff0c;实际运用非常广泛&#xff0c;加油&#xff01;需要的小伙伴请自取哦&#xff01;&#x1f4aa;&#x1f4aa;&#x1f4aa; 1 &#xf…