Python 如何手动编写一个自己的LRU缓存装饰器的方法实现

yizhihongxing

想要手动编写一个自己的LRU缓存装饰器,需要遵循以下几个步骤:

  1. 导入functools和collections模块

在Python中,functools模块用于操作函数,collections模块用于提供容器类型,如有序字典(OrderedDict)等。

import functools
import collections
  1. 定义装饰器函数

通过定义一个包装器函数,在函数执行前先检查是否已经存在缓存数据。若存在,则直接返回缓存的值,否则执行函数,并将其返回值加入缓存。

def lru_cache(max_size):
    """LRU缓存装饰器"""
    def decorator(func):
        cache = collections.OrderedDict()  # 设置有序字典缓存

        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            key = args + tuple(kwargs.items())  # 将参数和关键字参数组成元组作为缓存的键
            if key in cache:
                # 如果键已经存在,则将它移到有序字典的末尾,并将缓存值返回
                value = cache.pop(key)
                cache[key] = value
            else:
                # 如果键不存在,则执行函数,将返回值存入缓存
                value = func(*args, **kwargs)
                cache[key] = value

                # 如果缓存的键值对数量超过了max_size,则从有序字典的头部开始删除键值对,直到数量小于等于max_size
                if len(cache) > max_size:
                    cache.popitem(last=False)
            return value

        return wrapper

    return decorator

该装饰器函数可以接受一个最大缓存数量的参数,以及一个待装饰的函数。定义缓存时使用了有序字典,它可以按照键值对的插入顺序维护字典中元素的顺序。在wrapper函数中,先将函数的参数和关键字参数组成元组作为缓存的键,先根据键值查找是否存在缓存数据。如果缓存数据已经存在,则先将该键对应的值移动到有序字典的最后,以便于维护其访问顺序;如果缓存数据不存在,则需要执行函数,并缓存返回值,则将键值对添加到有序字典中,并根据最大缓存数量的设定,决定是否要删除最早的缓存数据。

  1. 使用装饰器

使用装饰器,在函数调用的时候可以自动地完成缓存的功能。

示例1:对于输入的参数,进行累加操作,去重后返回

@lru_cache(max_size=2)
def calculate(a,b,c):
    return sum(set([a,b,c]))

print(calculate(1, 2, 3))  # 计算并缓存,返回6
print(calculate(1, 2, 3))  # 直接从缓存中返回6
print(calculate(2, 3, 4))  # 计算并缓存,因为缓存达到最大数量,删除最早的缓存
print(calculate(1, 2, 3))  # 由于之前的计算结果已经被缓存,因此可以直接从缓存中返回6

示例2:对于输入的参数,将输入项中各单词翻转后再返回

@lru_cache(max_size=4)
def reverse_words(s):
    return ' '.join([word[::-1] for word in s.split()])

print(reverse_words('Hello World'))  # 计算并缓存,返回"olleH dlroW"
print(reverse_words('Hello Nice to Meet You'))  # 计算并缓存,返回"olleH eciN ot teeM uoY"
print(reverse_words('Hello World'))  # 直接从缓存中返回之前的结果"olleH dlroW"
print(reverse_words('Nice to Meet You Friend'))  # 计算并缓存,由于缓存已经满了,删除最早的缓存,返回"eciN ot teeM uoY dneirF"
print(reverse_words('Nice to Meet You'))  # 计算并缓存,由于缓存已经满了,删除最早的缓存,返回"eciN ot teeM uoY"
print(reverse_words('Hello Nice to Meet You'))  # 直接从缓存中返回之前的结果"olleH eciN ot teeM uoY"

在上述示例中,对于输入的不同参数,进行缓存,当达到缓存上限时,最早的缓存会被删除,并不断向有序字典的末尾插入新的缓存数据。从而实现了LRU缓存的功能。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python 如何手动编写一个自己的LRU缓存装饰器的方法实现 - Python技术站

(0)
上一篇 2023年5月13日
下一篇 2023年5月13日

相关文章

  • Python读取properties配置文件操作示例

    下面是详细讲解“Python读取properties配置文件操作示例”的完整攻略,希望对你有所帮助。 概述 properties(属性文件)是一种常见的配置文件类型,我们可以通过Python来读取和操作它。Python提供了ConfigParser模块来操作properties配置文件。 示例1:读取properties配置文件中的数据 假设我们有一个名为c…

    python 2023年6月3日
    00
  • 在 python / scikit 图像中获取图像的熵? [关闭]

    【问题标题】:Getting entropy of image in python / scikit image? [closed]在 python / scikit 图像中获取图像的熵? [关闭] 【发布时间】:2023-04-04 10:53:01 【问题描述】: 我注意到 Matlab 有一个 straightforward function 用于获取…

    Python开发 2023年4月6日
    00
  • Python正则表达式教程之二:捕获篇

    Python正则表达式教程之二:捕获篇 在Python正则表达式教程之一中,我们介绍了正则表达式的基本语法和常用函数。在本攻略中,我们将深入探讨则表达式的捕获功能,包括如何使用捕获组、非捕获组、零宽断言等功能。 捕获组 捕获组是正则表达式中的一种特殊语法,用于将匹配到的子字符串作为一个整体进行捕获。在正则表达式中,捕获组使用圆括()表示。下面是一个例子,演示…

    python 2023年5月14日
    00
  • python入门教程 python入门神图一张

    Python入门教程 这篇文章是一张 Python 入门神图的详细讲解。Python 是一种高级编程语言,具有易读易写、简洁明了、可扩展性强等优势,在Web开发、科学计算、数据处理等领域广泛应用。 下面我们来一步一步学习这张 Python 入门神图。 第1步:安装Python Python官网提供了Windows、macOS、Linux等多种版本的安装包,你…

    python 2023年5月13日
    00
  • 利用Python将每日一句定时推送至微信的实现方法

    题目描述: 本文将详细介绍如何使用Python实现将每日一句定时推送至微信的方法。 步骤说明: 准备工作 在开始实现之前,需要先准备好以下两个工作: 1.1 微信公众号后台账号 在微信公众号后台开通账号,并获取到开发者身份认证的相关信息。这个可以在微信公众平台上找到相关的文档进行操作。 1.2 Python爬虫代码 在Python环境下编写爬虫代码,用于获取…

    python 2023年5月19日
    00
  • EM算法的python实现的方法步骤

    以下是关于“EM算法的Python实现的方法步骤”的完整攻略: 简介 EM算法是一种常用的统计学习算法,用于估计含有隐变量的概率模型参数。在本教程中,我们将介绍如何使用Python实现EM算法,并提供两个示例。 方法步骤 EM算法的Python实现方法步骤如下: 初始化模型参数,包括隐变量的初始值和模型参数的初始值。 E步骤:根据当前模型参数和观测数据,计算…

    python 2023年5月14日
    00
  • Python全栈之基本数据类型

    Python全栈之基本数据类型攻略 1. 基本数据类型 Python 中具有以下基本数据类型:- 整数 (int)- 浮点数 (float)- 布尔值 (bool)- 字符串 (str) 整数 (int) 整数是没有小数部分的数字。在 Python 中,整数可以表示为十进制、八进制、十六进制等形式。我们可以使用内置的 type() 函数来查看变量的数据类型。…

    python 2023年5月13日
    00
  • python (logging) 日志按日期、大小回滚的操作

    下面是 Python 日志按日期、大小回滚的操作的完整攻略。 一、使用 logging 模块配置日志 在 Python 中,通常使用 logging 模块来记录日志。首先,我们需要通过 logging.basicConfig() 方法配置 logging 模块,以便在后续使用中直接调用。具体配置方式如下: import logging logging.bas…

    python 2023年6月3日
    00
合作推广
合作推广
分享本页
返回顶部