Reputation: 656
I have the below code defining the decorator
and the decorated
functions. When I call the decorated function, I am getting a TypeError: unhashable type: 'dict'. Where is the problem? Appreciate inputs. I am using jupyter
notebook on my desktop.
def memorize(func):
""" Store the results of a decorated function for last lookup"""
#store results in a dictionary that maps arguments to results
cache = {}
# define the wrappaer function that the decorator returns
def wrapper(*args,**kwargs):
#if these arguments haven't been seen before
if (args, kwargs) not in cache:
cache[(args,kwargs)] = func(*args, **kwargs)
return cache[(args, kwargs)]
return wrapper
@memorize
def slow_function(a,b):
print('Sleeping.....')
time.sleep(5)
return a+b
slow_function(3,7)
TypeError: unhashable type: 'dict'
Upvotes: 0
Views: 1082
Reputation: 1475
When you attempt to use (args,kwargs)
as key (or part of the key) in cache[(args,kwargs)]
, kwargs
is of dict
type. dict
types are not able to be used as keys in dictionaries. In fact, no mutable data structures can be used as keys in dictionaries.
An alternative is to use tuple(kwargs.items())
as this part of the key in the cache
dictionary, and translate back into dictionary as needed. This is only possible if you have no dictionaries (or other mutable objects) referenced within your kwargs
dictionary.
I have not personally used it, but frozendict
appears to convert dictionaries to immutable types.
Here is an example that illustrates the types of incoming positional arguments and keyword arguments.
def f(*args,**kwargs):
print(type(args),type(kwargs))
Output of f(1,2,3)
is
<class 'tuple'> <class 'dict'>
Upvotes: 1