关于python:如何为函数缓存散列*args**kwargs?

How to hash *args **kwargs for function cache?

我正在与xlwt合作,它对Excel文档中可定义的样式数有4K限制。

通常,人们会创建如下样式:

1
style = xlwt.easyxf("font: bold 1")

我只是换了一个

1
2
def cached_easyxf(self, format):
    return self._cache.setdefault(format, xlwt.easyxf(format))

很好用。现在,我发现有时我需要传递关键字参数,这让我想到:我应该如何散列args/kwargs签名?

我应该基于str(value)创建缓存密钥吗?泡菜?最健壮的是什么?

对于我的情况,看起来我可以将键/值转换为字符串并将其添加到键中…但是我现在想知道一种通用的方法来处理这个问题,比如说像arg=[1, 2, 3]这样的不可缓存类型。

1
2
3
4
def cached_call(*args, **kwargs):
    return cache.get(what_here)
cached_call('hello')
cached_call([1, 2, 3], {'1': True})

以下是在functools.lru缓存()中使用的技术:

1
2
3
4
5
kwd_mark = object()     # sentinel for separating args from kwargs

def cached_call(*args, **kwargs):
    key = args + (kwd_mark,) + tuple(sorted(kwargs.items()))
    return cache.get(key)

注意,上面的代码处理关键字参数,但不尝试处理列表等非哈希值。您使用列表str的想法是一个合理的开始。对于set对象,您需要首先对条目进行排序,str(sorted(someset))。其他对象可能没有有用的"repr"或"str"(也就是说,它们可能只显示对象类型和内存中的位置)。总之,处理任意不可显示的参数需要仔细考虑每个对象类型。