lru_cache
可以与大多数 Python 对象一起使用,但是为了确保缓存键的唯一性,返回值应该是可哈希(hashable)的。以下是一些可以与 lru_cache
一起使用的输出类型:
- 不可变内置类型:
- 整数 (
int
) - 浮点数 (
float
) - 字符串 (
str
) - 元组 (
tuple
),只要元组中的所有元素都是可哈希的 - 布尔值 (
bool
)
- 可哈希的用户定义类型:
- 如果你定义了一个类,并且为它提供了
__hash__
方法,那么这个类的实例可以被用作缓存键。
- 其他类型:
- 一些不可变或者具有固定状态的复杂对象,例如
frozenset
和datetime
对象,也可以作为缓存键。
以下是一些不能用作缓存键的类型:
- 可变内置类型:
- 列表 (
list
) - 字典 (
dict
) - 集合 (
set
)
- 具有状态的对象:
- 如果对象的状态可能会改变,那么它的哈希值可能会随之改变,这将导致缓存键失效。
- 大型数据结构:
- 例如
pandas
的DataFrame
或Series
,虽然它们是不可变的,但它们的哈希值计算成本可能很高,并且可能不是预期的缓存键。
- 没有实现
__hash__
方法的对象:
- 如果一个对象没有实现
__hash__
方法,或者它的__hash__
方法依赖于对象的状态,那么它不能用作缓存键。
如果你的函数返回的是不可哈希的类型,你可以考虑以下解决方案:
- 返回元组:如果函数返回的是列表或其他可变类型,你可以将其转换为元组,前提是元组中的所有元素都是可哈希的。
- 自定义缓存键:你可以使用函数参数作为缓存键,而不是依赖返回值。
- 使用
functools
模块的@cache
装饰器:Python 3.9 及以上版本中,functools
模块引入了一个新的@cache
装饰器,它不要求返回值是可哈希的,而是使用函数的参数作为缓存键。 - 持久化缓存:如果需要缓存大型数据结构,可以考虑将它们持久化到数据库或文件系统中。
记住,lru_cache
主要用于缓存函数的返回值,因此返回值应该是可哈希的,以便可以作为字典键使用。如果返回值不可哈希,你可能需要重新考虑如何实现缓存逻辑。