我正在研究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)
答案 0 :(得分:1)
该函数将一组函数参数转换为(a)可以进行哈希处理的序列,以及(b)为相同的参数返回相同的哈希值,如果使用相同的参数多次调用该函数。
显然,args
和kwargs
旨在成为泛型函数定义的位置和关键字参数:
def foo(*args, **kwargs):
pass
args
是一个列表,只要其所有元素都是可清除的,它就是可以清除的; kwargs
是dict
,但不是可混合类型。因此该函数使用.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)
10 和 20 位置参数按指定的顺序记录。
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'>)