Python之@cache装饰器的使用及说明

 更新时间:2025年12月22日 15:35:16   作者:Tipriest_  
@cache是Python3.9引入的新装饰器,用于缓存函数结果,避免重复计算,提高性能,它基于functools.lru_cache实现,支持无限大小缓存,适用于纯函数,使用示例包括递归斐波那契数列和模拟耗时计算,注意适用场景、参数限制和内存占用,与@lru_cache相比,@cache更简洁,但功能单一

一、@cache装饰器的基本概念

@cache 是 Python 3.9 引入的新功能,来源于标准库 functools 模块。它的作用是 对函数结果进行缓存(记忆化 memoization),从而避免重复计算,提高程序性能。

它的定义方式非常简单:

from functools import cache

@cache
def some_function(...):
    ...

当你用 @cache 修饰一个函数时,Python 会将该函数的输入参数与计算结果自动保存到一个缓存(字典)中。当后续调用该函数且参数完全相同时,不会再次执行函数体的计算逻辑,而是直接返回之前缓存的结果。

二、工作原理

@cache 装饰器内部其实是基于 functools.lru_cache 实现的,它等价于:

from functools import lru_cache

cache = lru_cache(maxsize=None)

也就是说:

  • 无限大小缓存maxsize=None 表示缓存结果没有数量限制,会根据需要一直增长(直到你的内存允许)。
  • 键值匹配:缓存根据参数 判断是否命中(必须是可哈希类型,如数字、字符串、元组等)。
  • 返回缓存结果:命中缓存时,直接返回结果而不执行函数计算。

三、使用示例

1. 基本示例:递归斐波那契数列

from functools import cache

@cache
def fib(n):
    print(f"计算 fib({n})")
    if n < 2:
        return n
    return fib(n - 1) + fib(n - 2)

print(fib(10))  # 第一次需要计算
print(fib(10))  # 第二次直接命中缓存,不会重新计算

运行效果:

  • 第一次调用会完整计算 fib(10),输出多行 "计算 fib(n)" 的提示信息。
  • 第二次调用相同参数,直接返回缓存值,不输出任何计算日志。

2. 模拟耗时计算

import time
from functools import cache

@cache
def slow_function(x):
    print(f"开始计算 {x}...")
    time.sleep(2)  # 模拟耗时
    return x * x

# 首次调用耗时
print(slow_function(5))

# 第二次调用相同参数时几乎立即返回
print(slow_function(5))

在实际场景中,如果一个函数计算代价高(如数据库查询、大文件解析、复杂计算等),使用 @cache 能显著减少重复工作。

四、注意事项

适用场景

  • 适合纯函数(函数结果只依赖输入参数,且不会产生副作用)。
  • 不适合需要每次实时更新的函数(例如获取当前时间、外部数据接口)。

参数限制

  • 参数必须可哈希(hashable),如整数、字符串、元组等。
  • 如果传入不可哈希类型(如列表、字典),会报错 TypeError: unhashable type

内存占用

  • @cache 默认缓存无限大小,可能造成内存占用增加;如果希望限制缓存大小,应使用 lru_cache(maxsize=...) 来控制。

缓存失效

  • @cache 没有内置超时或自动失效机制,缓存会一直保留直到程序结束或手动清除:
your_function.cache_clear()

五、@cache与@lru_cache的区别

特性@cache@lru_cache
缓存大小限制无限 (maxsize=None)可自定义 maxsize
缓存策略简单字典保存LRU(Least Recently Used)淘汰
用途适合始终命中缓存且参数种类有限适合缓存有限结果并自动淘汰旧数据

六、总结

  • @cache 能让函数的重复调用变得快速,尤其适合计算昂贵且参数唯一性高的场景。
  • 它是 @lru_cache(maxsize=None) 的简化版,功能单一但使用更简洁。
  • 使用时需注意内存占用和参数类型,确保函数是“纯”的(无副作用)。
  • 对于需要缓存大小控制的场景或更复杂的缓存管理,应使用 lru_cache

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • python 协程并发数控制

    python 协程并发数控制

    这篇文章主要介绍了python 协程并发数控制,文章基于python的相关资料展开对主题烦人详细内容介绍,需要的小伙伴可以参考一下
    2022-05-05
  • 浅谈Python 中整型对象的存储问题

    浅谈Python 中整型对象的存储问题

    这篇文章主要介绍了浅谈Python 中整型对象的存储问题的相关资料,需要的朋友可以参考下
    2016-05-05
  • 关于keras多任务多loss回传的思考

    关于keras多任务多loss回传的思考

    这篇文章主要介绍了关于keras多任务多loss回传的思考,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-05-05
  • Django框架安装及项目创建过程解析

    Django框架安装及项目创建过程解析

    这篇文章主要介绍了Django框架安装及项目创建过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09
  • PyTorch使用tensorboard的SummaryWriter报错问题解决方案

    PyTorch使用tensorboard的SummaryWriter报错问题解决方案

    PyTorch使用tensorboard可以显示网络运行情况,但偶尔使用SummaryWriter时遇到Segmentation fault错误,这篇文章主要介绍了PyTorch使用tensorboard的SummaryWriter报错问题解决方案,需要的朋友可以参考下
    2024-06-06
  • Python单元测试框架unittest简明使用实例

    Python单元测试框架unittest简明使用实例

    这篇文章主要介绍了Python单元测试框架unittest简明使用实例,本文讲解了基本测试步骤、和测试实例,需要的朋友可以参考下
    2015-04-04
  • Python二维码生成库qrcode安装和使用示例

    Python二维码生成库qrcode安装和使用示例

    这篇文章主要介绍了Python二维码生成库qrcode安装和使用示例,本文讲解了qrcode的安装、生成二维码、生成带图标的二维码等内容,需要的朋友可以参考下
    2014-12-12
  • python使用devpi实现镜像源代理完整指南

    python使用devpi实现镜像源代理完整指南

    这篇文章主要为大家详细介绍了如何使用devpi实现python镜像源代理,包括缓存加速,私有仓库和版本控制,文中的示例代码讲解详细,有需要的可以了解下
    2025-05-05
  • Python实现复杂的事件驱动架构

    Python实现复杂的事件驱动架构

    事件驱动架构(Event-Driven Architecture, EDA)是一种软件设计模式,它基于事件的产生、传播和处理进行系统的构建,下面我们来看看如何在 Python 中实现复杂的事件驱动架构吧
    2024-12-12
  • 使用PyCharm调试程序实现过程

    使用PyCharm调试程序实现过程

    这篇文章主要介绍了使用PyCharm调试程序实现过程,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11

最新评论