返回

Python的缓存装饰器全攻略:@lru_cache、@cache和@cached_property

后端

揭秘 Python 缓存装饰器:提升代码执行效率的利器

简介

在 Python 中,我们经常需要处理计算量大的任务。为了提高代码效率,我们可以利用内置的缓存装饰器。本文将深入探讨三个常用的缓存装饰器:@lru_cache、@cache 和 @cached_property,全面阐述它们的用法和适用场景,帮助你掌握 Python 中的缓存技巧。

@lru_cache:轻量级函数缓存

概念:

@lru_cache 是一个函数缓存装饰器,它通过记住函数的输入和输出,来避免重复计算。当函数再次被调用时,如果输入参数与之前调用时相同,则直接从缓存中返回结果。

代码示例:

import functools

@functools.lru_cache()
def fibonacci(n):
    if n < 2:
        return n
    else:
        return fibonacci(n-1) + fibonacci(n-2)

print(fibonacci(35))  # 计算并缓存结果
print(fibonacci(35))  # 直接从缓存中获取结果

适用场景:

  • 适用于计算量大、结果不变的函数,如数学函数、查找表等。
  • 可有效避免重复计算,提高代码运行速度。

@cache:万能缓存工具

概念:

@cache 是一个通用缓存装饰器,它不仅可以缓存函数,还可以缓存任何可哈希的对象,如类、方法、数据结构等。

代码示例:

import functools

class MyClass:
    @functools.cache
    def my_method(self, x, y):
        return x + y

obj = MyClass()
print(obj.my_method(1, 2))  # 计算并缓存结果
print(obj.my_method(1, 2))  # 直接从缓存中获取结果

适用场景:

  • 适用于计算量大、结果可能发生变化的函数或对象,如数据库查询、文件读取等。
  • 提供了更大的灵活性,可缓存各种类型的数据。

@cached_property:成员方法缓存

概念:

@cached_property 是一个类成员方法缓存装饰器,它专门用于缓存类的方法。当方法再次被调用时,如果实例和方法参数与之前调用时相同,则直接从缓存中返回结果。

代码示例:

class MyClass:
    @cached_property
    def my_property(self):
        return len(self.name)

obj = MyClass()
obj.name = "John Doe"
print(obj.my_property)  # 计算并缓存结果
print(obj.my_property)  # 直接从缓存中获取结果

适用场景:

  • 适用于计算量大、结果与实例状态相关的方法,如对象的长度、摘要等。
  • 有助于优化类的性能,避免重复计算。

适用场景建议

为了帮助你选择合适的缓存装饰器,以下是一些建议:

  • @lru_cache: 计算量大、结果不变的函数。
  • @cache: 计算量大、结果可能发生变化的函数或对象。
  • @cached_property: 计算量大、结果与实例状态相关的方法。

结论

Python 内置的缓存装饰器是一个非常有用的工具,可以帮助我们大幅提升代码效率。通过合理使用这些装饰器,我们可以避免重复计算,提高代码的运行速度。掌握这些缓存技巧,将使你在 Python 开发中如虎添翼。

常见问题解答

  1. 缓存装饰器会影响内存使用吗?

是的,缓存装饰器会占用额外的内存来存储缓存数据。

  1. 缓存装饰器是否总是能提高性能?

不一定。对于计算量较小的函数,缓存装饰器可能会增加开销,反而降低性能。

  1. 如何清除缓存?

lru_cache 和 cache 装饰器提供了一个 clear() 方法,用于清除缓存。

  1. cached_property 装饰器适用于所有方法吗?

是的,cached_property 装饰器适用于类中的所有方法。

  1. 是否可以在多个函数或类中同时使用这些装饰器?

是的,可以同时在不同的函数或类中使用这些装饰器。