10分钟掌握Python缓存

python · 浏览次数 : 0

小编点评

本文主要介绍了Python中不同缓存组件的使用场景和使用样例。首先,文章概述了选择缓存的重要性,并简要介绍了Python中可用的缓存组件。接着,详细讨论了各种缓存组件,包括它们的定义、适用场景和示例代码。最后,文章总结了如何根据具体需求和使用场景选择合适的缓存组件。 1. **Python缓存分类**: 文章介绍了Python中的缓存分类,包括内存缓存、本地文件缓存和分布式缓存。对于小规模数据缓存,推荐使用functools.lru_cache。如果需要持久化或分布式缓存,可以考虑使用diskcache或Redis。 2. **Python内存缓存分类**: 详细讨论了Python中多种内存缓存组件,如functools.lru_cache、cachetools、django.core.cache、Flask-Caching、requests_cache、dogpile.cache和joblib.Memory。这些组件各有特点,适用于不同的场景。 3. **cachetools使用案例**: 文章通过一个实际项目案例,展示了如何使用cachetools库来实现缓存工具类。通过这个案例,读者可以了解cachetools在分布式系统中的实际应用。 总的来说,本文为Python开发者提供了一个全面的缓存组件使用指南,帮助他们在项目中做出合适的选择,提高代码性能和用户体验。

正文

全文速览

  • 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缓存相似的内容:

10分钟掌握Python缓存

全文速览 python的不同缓存组件的使用场景和使用样例 cachetools的使用 项目背景 代码检查项目,需要存储每一步检查的中间结果,最终把结果汇总并写入文件中 在中间结果的存储中 可以使用context进行上下文的传递,但是整体对代码改动比较大,违背了开闭原则 也可以利用缓存存储,处理完成之

传统软件如何SaaS化改造,10个问答带你掌握最优解

摘要:如果您所在企业希望实行SaaS化改造,可访问了解华为云开发者技术团队的SaaS支持计划。 本文分享自华为云社区《【云享问答】第1期:传统软件如何SaaS化改造,10个问答带你掌握最优解!》,作者:技术火炬手。 如果您所在企业希望实行SaaS化改造,可访问了解华为云开发者技术团队的SaaS支持计

掌握Go的运行时:从编译到执行

> 讲解Go语言从编译到执行全周期流程,每一部分都会包含丰富的技术细节和实际的代码示例,帮助大家理解。 > 关注微信公众号【TechLeadCloud】,分享互联网架构、云服务技术的全维度知识。作者拥有10+年互联网服务架构、AI产品研发经验、团队管理经验,同济本复旦硕,复旦机器人智能实验室成员,阿

4.10 x64dbg 反汇编功能的封装

LyScript 插件提供的反汇编系列函数虽然能够实现基本的反汇编功能,但在实际使用中,可能会遇到一些更为复杂的需求,此时就需要根据自身需要进行二次开发,以实现更加高级的功能。本章将继续深入探索反汇编功能,并将介绍如何实现反汇编代码的检索、获取上下一条代码等功能。这些功能对于分析和调试代码都非常有用,因此是书中重要的内容之一。在本章的学习过程中,读者不仅可以掌握反汇编的基础知识和技巧,还能够了解如

GAN!生成对抗网络GAN全维度介绍与实战

> 本文为生成对抗网络GAN的研究者和实践者提供全面、深入和实用的指导。通过本文的理论解释和实际操作指南,读者能够掌握GAN的核心概念,理解其工作原理,学会设计和训练自己的GAN模型,并能够对结果进行有效的分析和评估。 > 作者 TechLead,拥有10+年互联网服务架构、AI产品研发经验、团队管

10分钟搞定Mysql主从部署配置

流程 Master数据库安装 Slave数据库安装 配置Master数据库 配置Slave数据库 网络信息 Master数据库IP:192.168.198.133 Slave数据库IP:192.168.198.132 配置Master数据库 在Master数据库安装完毕后,修改/etc/my.cnf

10分钟了解Flink SQL使用

Flink 是一个流处理和批处理统一的大数据框架,专门为高吞吐量和低延迟而设计。开发者可以使用SQL进行流批统一处理,大大简化了数据处理的复杂性。本文将介绍Flink SQL的基本原理、使用方法、流批统一,并通过几个例子进行实践。 1、Flink SQL基本原理 Flink SQL建立在Apache

10分钟带你徒手做个Java线程池

摘要:花10分钟开发一个极简版的Java线程池,让小伙伴们更好的理解线程池的核心原理。 本文分享自华为云社区《放大招了,冰河带你10分钟手撸Java线程池,yyds,赶快收藏吧》,作者:冰 河。 Java线程池核心原理 看过Java线程池源码的小伙伴都知道,在Java线程池中最核心的类就是Threa

#PowerBi 10分钟学会,以X为结尾的聚合函数

前言 在Power BI中,我们经常需要对数据进行聚合计算,比如求和、求平均、求最大值等。 Power BI提供了一系列的聚合函数,可以用来对表中列的值进行聚合然后返回一个值。这些函数通常只需要一个参数,就是要聚合的列名。如SUM(‘销售表’[销量]),就是求销售表里的销量总和。 但是有时候,我们需

#Powerbi 10分钟,理解 Rankx 排名函数

一:本文思维导图及示例数据图 1.1思维导图 1.2 示例数据图 二:度量值示例 2.1 函数简介 RANKX 首先为的每一行计值表达式,将结果临时存储为一个值列表。然后在当前筛选上下文中计值,将得到的结果与列表中的值进行比较,根据排名规则和的设置,返回最终排名。 2.2 产品排名(稠密)度量值 这