Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python缓存:TypeError:unhable type:';dict';_Python_Python 3.x - Fatal编程技术网

Python缓存:TypeError:unhable type:';dict';

Python缓存:TypeError:unhable type:';dict';,python,python-3.x,Python,Python 3.x,我正在尝试用Python实现一个缓存函数。代码如下所示: def memoize(func): """Store the results of the decorated function for fast lookup """ # Store results in a dict that maps arguments to results cache = {} def wrapper(*ar

我正在尝试用Python实现一个缓存函数。代码如下所示:

def memoize(func):
    """Store the results of the decorated function for fast lookup
    """

    # Store results in a dict that maps arguments to results
    cache = {}

    def wrapper(*args, **kwargs):
        # If these arguments haven't been seen before, call func() and store the result.
        if (args, kwargs) not in cache:        
            cache[(args, kwargs)] = func(*args, **kwargs)          
        return cache[(args, kwargs)]

    return wrapper

@memoize
def add(a, b):
    print('Sleeping...')
    return a + b

add(1, 2)
当我运行代码时,我得到
TypeError:unhabable类型:“dict”


怎么了?

发生这种情况是因为您试图将字典作为键,这是一个问题。您可以使用
frozenset()
冻结字典,以便它在这一行中

cache[(args, kwargs)] = func(*args, **kwargs)

您使用
kwargs
作为键的一部分,它是
dict
dict
s是可变的,
dict
s的键必须是不可变的。

dict的键必须是可散列的。您提供了一个不可损坏的键
(args,kwargs)
,因为
kwargs
是一个不可损坏的
dict

要解决此问题,您应该从
args
kwargs
的组合中生成一个哈希键。例如,您可以使用(假设
args
kwargs
的所有值都是可散列的)



Dict是不可散列的,这意味着您不能在需要对对象进行散列的操作中使用它。将对象用作dict中的键就是其中之一

具体来说,奖项是一本词典,您正试图将其用作另一本词典的密钥的一部分

要使其工作,您应该创建一个函数来接收奖励,并将其转换为一个数字或字符串,该数字或字符串对任何具有相同内容的词典都具有指纹

作为旁注,如果您将任何dict作为参数、匿名或关键字传递,也可能发生这种情况。如果您选择使用此解决方案,我的建议是在args和kwargs中执行此操作,并递归检查args中是否有dict

另一方面,在functools模块上,本地缓存使用lru_缓存,缓存操作使用cachetools,异步缓存使用aiocache,异步缓存支持除本地缓存以外最流行的后端

key = ( args , tuple((kwargs.items())))
def memoize(func):
    """Store the results of the decorated function for fast lookup
    """

    # Store results in a dict that maps arguments to results
    cache = {}

    def wrapper(*args, **kwargs):
        # If these arguments haven't been seen before, call func() and store the result.
        key = ( args , tuple((kwargs.items())))
        if key not in cache:        
            cache[key] = cc = func(*args, **kwargs)          
            return cc
        return cache[key]

    return wrapper

@memoize
def add(a, b):
    print('Sleeping...')
    return a + b

print(add(1, 2))