Srinivas
Srinivas

Reputation: 656

TypeError: unhashable type: 'dict' while applying a decorator function

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

Answers (1)

jpf
jpf

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

Related Questions