将@ functools.lru_cache与字典参数一起使用 [英] Using @functools.lru_cache with dictionary arguments

查看:100
本文介绍了将@ functools.lru_cache与字典参数一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个方法(其中包括一个字典)作为参数。该方法正在解析字符串,并且字典提供了一些子字符串的替换,因此它不必是可变的。

I have a method that takes (among others) a dictionary as an argument. The method is parsing strings and the dictionary provides replacements for some substrings, so it doesn't have to be mutable.

此函数经常调用,并且在冗余元素上所以我认为缓存它可以提高效率。

This function is called quite often, and on redundant elements so I figured that caching it would improve its efficiency.

但是,正如您可能已经猜到的那样,由于 dict 是可变且不可散列的 @ functools.lru_cache 无法装饰我的函数。那么我该如何克服呢?

But, as you may have guessed, since dict is mutable and thus not hashable, @functools.lru_cache can't decorate my function. So how can I overcome this?

如果仅需要标准库类和方法,则奖励积分。理想情况下,如果它在标准库中存在某种 frozendict ,而我却没有看到它会使我的生活变得如此。

Bonus point if it needs only standard library classes and methods. Ideally if it exists some kind of frozendict in standard library that I haven't seen it would make my day.

PS: namedtuple 仅在不得已时使用,因为这将需要很大的语法转换。

PS: namedtuple only in last resort, since it would need a big syntax shift.

推荐答案

不要使用自定义的可哈希字典,而是使用它,避免重新发明轮子!

Instead of using a custom hashable dictionary, use this and avoid reinventing the wheel! It's a frozen dictionary that's all hashable.

https:/ /pypi.org/project/frozendict/

代码:

def freezeargs(func):
    """Transform mutable dictionnary
    Into immutable
    Useful to be compatible with cache
    """

    @functools.wraps(func)
    def wrapped(*args, **kwargs):
        args = tuple([frozendict(arg) if isinstance(arg, dict) else arg for arg in args])
        kwargs = {k: frozendict(v) if isinstance(v, dict) else v for k, v in kwargs.items()}
        return func(*args, **kwargs)
    return wrapped

,然后

@freezeargs
@lru_cache
def func(...):
    pass

从@fast_cen的答案中提取的代码

Code taken from @fast_cen 's answer

注意:这不适用于递归数据结构;例如,您可能有一个参数列表,该列表不可散列。邀请您进行环绕包装,使其深入数据结构,并冻结每个 dict 和每个 list 元组。

Note: this does not work on recursive datastructures; for example, you might have an argument that's a list, which is unhashable. You are invited to make the wrapping recursive, such that it goes deep into the data structure and makes every dict frozen and every list tuple.

(我知道OP不再需要解决方案了,但我来这里是寻找相同的解决方案,所以将其留给后代使用)

(I know that OP nolonger wants a solution, but I came here looking for the same solution, so leaving this for future generations)

这篇关于将@ functools.lru_cache与字典参数一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆