python - 在具有常量但不可散列对象的函数上使用 functools.lru_cache

标签 python python-3.x functools

是否可以使用 functools.lru_cache 来缓存由 functools.partial 创建的部分函数?

我的问题是一个函数,该函数采用可散列参数和常量、不可散列对象(例如 NumPy 数组)。

考虑这个玩具示例:

import numpy as np
from functools import lru_cache, partial

def foo(key, array):
    print('%s:' % key, array)
a = np.array([1,2,3])

因为 NumPy 数组不可哈希,所以这行不通:

@lru_cache(maxsize=None)
def foo(key, array):
    print('%s:' % key, array)
foo(1, a)

正如预期的那样,您会收到以下错误:

/Users/ch/miniconda/envs/sci34/lib/python3.4/functools.py in __init__(self, tup, hash)
    349     def __init__(self, tup, hash=hash):
    350         self[:] = tup
--> 351         self.hashvalue = hash(tup)
    352 
    353     def __hash__(self):

TypeError: unhashable type: 'numpy.ndarray'

所以我的下一个想法是使用 functools.partial 摆脱 NumPy 数组(无论如何它是常量)

pfoo = partial(foo, array=a)
pfoo(2)

所以现在我有了一个只接受可散列参数的函数,并且应该非常适合 lru_cache。但是在这种情况下可以使用lru_cache吗?我不能将它用作包装函数而不是 @lru_cache 装饰器,可以吗?

有什么巧妙的方法可以解决这个问题吗?

最佳答案

由于数组是常量,您可以使用包装器围绕实际的 lru 缓存函数并简单地将键值传递给它:

from functools import lru_cache, partial
import numpy as np


def lru_wrapper(array=None):
    @lru_cache(maxsize=None)
    def foo(key):
        return '%s:' % key, array
    return foo


arr = np.array([1, 2, 3])
func = lru_wrapper(array=arr)

for x in [0, 0, 1, 2, 2, 1, 2, 0]:
    print (func(x))

print (func.cache_info())

输出:

('0:', array([1, 2, 3]))
('0:', array([1, 2, 3]))
('1:', array([1, 2, 3]))
('2:', array([1, 2, 3]))
('2:', array([1, 2, 3]))
('1:', array([1, 2, 3]))
('2:', array([1, 2, 3]))
('0:', array([1, 2, 3]))
CacheInfo(hits=5, misses=3, maxsize=None, currsize=3)

关于python - 在具有常量但不可散列对象的函数上使用 functools.lru_cache,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37609772/

相关文章:

python - 从 C 访问 Numpy 矩阵作为 3D 数组

python - 从 pandas.Series 中选择局部最小值和最大值

python - 自定义 QStyledItemDelegate : adding bold items

excel - 使用 Python Selenium 下载 Excel 文件

python - Total_ordering 和类继承

python - 如何使用理解来减少字典值中的集合?

python - 可以自动将数据从 memcached 传输到 mysql DB 吗?

python - 在数据类中创建类变量的正确方法

python-3.x - xpath 连接来自多个元素的文本 python

python - 类成员函数的 Memoize 包装器返回部分值