全文速览

  • python的不同缓存组件的使用场景和使用样例
  • cachetools的使用

项目背景

代码检查项目,需要存储每一步检查的中间结果,最终把结果汇总并写入文件中

在中间结果的存储中

  • 可以使用context进行上下文的传递,但是整体对代码改动比较大,违背了开闭原则
  • 也可以利用缓存存储,处理完成之后再统一读缓存并写入文件

在权衡了不同方案后,我决定采用缓存来存储中间结果。接下来,我将探讨 Python 中可用缓存组件。

python缓存分类

决定选择缓存,那么python中都有哪些类型的缓存呢?

1. 使用内存缓存(如 functools.lru_cache

这是最简单的一种缓存方法,适用于小规模的数据缓存。使用 functools.lru_cache 可以对函数结果进行缓存。

from functools import lru_cache

@lru_cache(maxsize=128)
def expensive_function(param1, param2):
# 进行一些耗时的操作
return result

2. 使用本地文件缓存(如 diskcache

如果缓存的数据较大,或者需要跨进程共享缓存,可以使用文件系统缓存库,例如 diskcache

import diskcache as dc

cache = dc.Cache('/tmp/mycache')

@cache.memoize(expire=3600)
def expensive_function(param1, param2):
# 进行一些耗时的操作
return result

3. 使用分布式缓存(如 Redis)

对于需要跨多个应用实例共享缓存的数据,可以使用 Redis 这样的分布式缓存系统。

import redis
import pickle r = redis.StrictRedis(host='localhost', port=6379, db=0) def expensive_function(param1, param2):
key = f"{param1}_{param2}"
cached_result = r.get(key)
if cached_result:
return pickle.loads(cached_result) result = # 进行一些耗时的操作
r.set(key, pickle.dumps(result), ex=3600) # 设置缓存过期时间为1小时
return result

总结

如果只是简单的小规模缓存,lru_cache 足够;如果需要持久化或分布式缓存,可以考虑使用 diskcache 或 Redis;如果使用了 Web 框架,使用框架自带的缓存功能会更方便。

python内存缓存分类

兼顾速度和成本以及实现的复杂度,最终决定使用内存缓存,在 Python 中,内存缓存组件有许多选择,每种都有其特定的优点和适用场景。以下是一些常见的内存缓存组件:

1. functools.lru_cache

lru_cache 是 Python 标准库中的一个装饰器,用于缓存函数的返回结果,基于最近最少使用(LRU)策略。

from functools import lru_cache

@lru_cache(maxsize=128)
def expensive_function(param1, param2):
# 进行一些耗时的操作
return result

2. cachetools

cachetools 是一个第三方库,提供了多种缓存策略,包括 LRU、LFU、TTL(基于时间的缓存)等。

from cachetools import LRUCache, cached

cache = LRUCache(maxsize=100)

@cached(cache)
def expensive_function(param1, param2):
# 进行一些耗时的操作
return result

3. django.core.cache

如果使用 Django 框架,Django 自带了缓存框架,支持多种缓存后端,包括内存缓存。

settings.py 中配置内存缓存:

CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': 'unique-snowflake',
}
}

4. Flask-Caching

如果使用 Flask 框架,Flask-Caching 插件可以方便地实现内存缓存。

from flask import Flask
from flask_caching import Cache app = Flask(__name__)
cache = Cache(app, config={'CACHE_TYPE': 'simple'}) @app.route('/expensive')
@cache.cached(timeout=60)
def expensive_function():
# 进行一些耗时的操作
return result

5. requests_cache

requests_cache 是一个专门用于缓存 HTTP 请求的库,支持多种缓存后端,包括内存缓存。

import requests
import requests_cache requests_cache.install_cache('demo_cache', backend='memory', expire_after=3600) response = requests.get('https://api.example.com/data')

6. dogpile.cache

dogpile.cache 是一个更高级的缓存库,提供了灵活的缓存后端和缓存失效策略。

from dogpile.cache import make_region

region = make_region().configure(
'dogpile.cache.memory',
expiration_time=3600
) @region.cache_on_arguments()
def expensive_function(param1, param2):
# 进行一些耗时的操作
return result

7. joblib.Memory

joblib.Memory 常用于科学计算和数据处理领域,用于缓存函数的计算结果。

from joblib import Memory

memory = Memory(location='/tmp/joblib_cache', verbose=0)

@memory.cache
def expensive_function(param1, param2):
# 进行一些耗时的操作
return result

总结

根据具体需求和使用场景选择合适的内存缓存组件。对于简单的缓存需求,可以使用 functools.lru_cachecachetools。对于 Web 应用,django.core.cacheFlask-Caching 是不错的选择。对于 HTTP 请求缓存,可以使用 requests_cache。对于科学计算,joblib.Memory 是一个好选择。

cachetools使用

我的项目是一个命令行执行的项目,综合考量最终决定选择cachetools

  1. 安装 cachetools
pip install cachetools
  1. 实现缓存工具类
from cachetools import LRUCache
from cachetools import Cache
from siada.cr.logger.logger import logger class CacheUtils:
"""
缓存工具类
""" def __init__(self, cache: Cache = None):
self.cache = cache if cache else LRUCache(maxsize=100) def get_value(self, cache_key: str):
value = self.cache.get(cache_key, None)
if value is not None:
logger.info(f"Cache hit for key: {cache_key}")
else:
logger.info(f"Cache miss for key: {cache_key}")
return value def set_key_value(self, cache_key: str, value):
self.cache[cache_key] = value
logger.info(f"Set cache key: {cache_key} with value: {value}") def set_key_list(self, cache_key: str, value):
v = self.cache.get(cache_key, None)
if v is not None:
v.append(value)
else:
self.cache[cache_key] = [value] def clear_cache(self):
self.cache.clear() # TODO 如果后续生成过程改为多线程并发,需考虑数据竞争问题
cache = CacheUtils()

更多惊喜

我还将定期分享:

  • 最新互联网资讯:让你时刻掌握行业动态。

  • AI前沿新闻:紧跟技术潮流,不断提升自我。

  • 技术分享与职业发展:助你在职业生涯中走得更远、更稳。

  • 程序员生活趣事:让你在忙碌的工作之余找到共鸣与乐趣。

关注回复【1024】惊喜等你来拿!

点击查看惊喜

敬请关注【程序员世杰】

10分钟掌握Python缓存的更多相关文章

  1. 10分钟上手python pandas

    目录 Environment 开始 对象创建 查看数据 选择 直接选择 按标签选择 按位置选择 布尔索引 设置 缺失数据 操作 统计 应用(apply) 直方图化(Histogramming) 字符串 ...

  2. 10分钟学会Python函数基础知识

    看完本文大概需要8分钟,看完后,仔细看下代码,认真回一下,函数基本知识就OK了.最好还是把代码敲一下. 一.函数基础 简单地说,一个函数就是一组Python语句的组合,它们可以在程序中运行一次或多次运 ...

  3. 10分钟用Python告诉你两个机器人聊天能聊出什么火花

    欲直接下载代码文件,关注我们的公众号哦!查看历史消息即可! 现在不是讲各种各样的人工智能嘛,AI下棋,AI客服,AI玩家--其实我一直很好奇,两个AI碰上会怎样,比如一起下棋,一起打游戏-- 今天做个 ...

  4. 10分钟学会Python

    #1. 语法 Python中没有强制的语句终止字符,代码块是通过缩进来指示的.缩进表示一个代码块的开始,逆缩进则表示一个代码块的结束.一般用4个空格来表示缩进. 声明以冒号(:)字符结束,并且开启一个 ...

  5. 程序员如何 10 分钟用 Python 画出蒙娜丽莎?

    之前看到过很多头条,说哪国某人坚持了多少年自学使用excel画画,效果十分惊艳.对于他们的耐心我十分敬佩. 但是作为一个程序员,自然也得挑战一下自己. 这种需求,我们十分钟就可以完成! 基本思路   ...

  6. [转]10分钟入门python

    本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为Rocrocket Wu. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体 ...

  7. 10分钟用Python爬取最近很火的复联4影评

    欲直接下载代码文件,关注我们的公众号哦!查看历史消息即可! <复仇者联盟4:终局之战>已经上映快三个星期了,全球票房破24亿美元,国内票房破40亿人民币. 虽然现在热度逐渐下降,但是我们还 ...

  8. 【python】10分钟教你用python打造贪吃蛇超详细教程

    10分钟教你用python打造贪吃蛇超详细教程 在家闲着没妹子约, 刚好最近又学了一下python,听说pygame挺好玩的.今天就在家研究一下, 弄了个贪吃蛇出来.希望大家喜欢. 先看程序效果: 0 ...

  9. 10分钟教你用Python打造天气机器人+关键字自动回复+定时发送

    01 前言 Hello,各位小伙伴.自上次我们介绍了Python实现天气预报的功能以后,那个小程序还有诸多不完善的地方,今天,我们再次来完善一下我们的小程序.比如我们想给机器人发“天气”等关键字,它就 ...

  10. 10分钟教你用Python打造微信天气预报机器人

    01 前言 最近武汉的天气越来越恶劣了.动不动就下雨,所以,拥有一款好的天气预报工具,对于我们大学生来说,还真是挺重要的了.好了,自己动手,丰衣足食,我们来用Python打造一个天气预报的微信机器人吧 ...

随机推荐

  1. netcore3.1 程序在cento8下运行selenium

    我需要在linux下运行selenium抓取数据,本人不熟悉Python,所以只能用netcore.在带linux界面上运行爬取程序,驱动chromedriver比较简单.界面化安装好chrome,下 ...

  2. Go-Zero微服务快速入门和最佳实践(一)

    前言 并发编程和分布式微服务是我们Gopher升职加薪的关键. 毕竟Go基础很容易搞定,不管你是否有编程经验,都可以比较快速的入门Go语言进行简单项目的开发. 虽说好上手,但是想和别人拉开差距,提高自 ...

  3. R6_ES在互联网公司应用案例汇总参考

    Elasticsearch 是一个实时分布式搜索数据分析引擎,内部使用lucene做索引与搜索,能够解决常规和各种类型数据的存储及检索需求,典型的应用场景有:数据分析,站内搜索,ELK,电商等,主要特 ...

  4. python 操作 xlsx

    目录 读取/写入:openpyxl demo1 读取/写入:openpyxl demo1 import openpyxl import os # 创建excel def write_excel_xls ...

  5. gin框架对接快递100 查询快递跟踪记录 Golang实现快递查询

    参考ui效果: https://www.kuaidi100.com/?from=openv gin框架: 请求地址 http://localhost:8822/kd100/auto_com_num?n ...

  6. 计算机网络基础 — Linux 虚拟路由器

    目录 文章目录 目录 前文列表 前言 Neutron L3 agent 概述 L3 agent的配置 虚拟路由器实现原理 总结 前文列表 <计算机网络基础 - 以太网> <计算机网络 ...

  7. AIRIOT物联网平台助力油库自动化升级 实现业务场景全覆盖

      随着我国石油工业的飞速发展,油库规模迅速扩大,油库系统逐渐完善起来.石油行业属于高风险行业,所以石油化工产品在储存.运输和生产各个环节,均有极高的安监.环保.应急的管理要求.通常情况下,油库容量. ...

  8. 自动化部署elasticsearch三节点集群

    什么是Elasticsearch? Elasticsearch 是一个开源的分布式搜索和分析引擎,构建在 Apache Lucene 的基础上.它提供了一个分布式多租户的全文搜索引擎,具有实时分析功能 ...

  9. Vue.js条件渲染与列表渲染指南

    title: Vue.js条件渲染与列表渲染指南 date: 2024/5/26 20:11:49 updated: 2024/5/26 20:11:49 categories: 前端开发 tags: ...

  10. .NET Core应用程序每次启动后使用string.GetHashCode()方法获取到的哈希值(hash)不相同

    前言 如标题所述,在ASP.NET Core应用程序中,使用string.GetHashCode()方法去获取字符串的哈希值,但每次重启这个ASP.NET Core应用程序之后,同样的字符串的哈希值( ...