Python的LRU缓存代码中的_make_key函数

时间:2015-08-18 19:02:03

标签: python lru

我正在研究Python的最近最少使用(LRU)缓存实施here

有人可以解释_make_key功能在做什么吗?

def _make_key(args, kwds, typed,
             kwd_mark = (object(),),
             fasttypes = {int, str, frozenset, type(None)},
             sorted=sorted, tuple=tuple, type=type, len=len):
    'Make a cache key from optionally typed positional and keyword arguments'
    key = args
    if kwds:
        sorted_items = sorted(kwds.items())
        key += kwd_mark
        for item in sorted_items:
            key += item
    if typed:
        key += tuple(type(v) for v in args)
        if kwds:
            key += tuple(type(v) for k, v in sorted_items)
    elif len(key) == 1 and type(key[0]) in fasttypes:
        return key[0]
    return _HashedSeq(key)

2 个答案:

答案 0 :(得分:1)

该函数将一组函数参数转换为(a)可以进行哈希处理的序列,以及(b)为相同的参数返回相同的哈希值,如果使用相同的参数多次调用该函数。

显然,argskwargs旨在成为泛型函数定义的位置和关键字参数:

def foo(*args, **kwargs):
    pass

args是一个列表,只要其所有元素都是可清除的,它就是可以清除的; kwargsdict,但不是可混合类型。因此该函数使用.items()将其转换为键值对列表;然后对它进行排序,因为列表的哈希值对元素的顺序很敏感,dict可以按任意顺序列出其项目。

kwd_mark的目的是确保关键字参数不会与位置参数混淆,这些参数可能恰好由与kwargs项相同的键值对组成。作为默认参数,在定义函数时分配其值;这保证了它的sentinel对象永远不会作为函数参数出现。

答案 1 :(得分:0)

总结

_make_key() 函数将参数扁平化为一个紧凑的元组,可用于确定两个调用的参数是否相同。

生成的密钥

调用 f(10, 20, x=30, y=40)f(10, 20, y=40, x=30) 都具有相同的键:

(10, 20, <object object at 0x7fae2bb25040>, 'x', 30, 'y', 40)

1020 位置参数按指定的顺序记录。

kwd_mark 将关键字参数与位置参数分开。

对关键字参数进行排序,以便将 x=30, y=40 识别为与 y=40, x=30 相同。

如果 typed 为真,则键也记录参数类型:

(10, 20,                            # positional args
<object object at 0x7fae2bb25040>,  # kwd_mark
'x', 30, 'y', 40,                   # keyword args
<class 'int'>, <class 'int'>,       # types of the args  
<class 'int'>, <class 'int'>)