Search code examples
pythondjangodjango-cache

Django: cache a dictionary containing a lambda function


I am trying to save a dictionary that contains a lambda function in django.core.cache. The example below fails silently.

from django.core.cache import cache
cache.set("lambda", {"name": "lambda function", "function":lambda x: x+1})

cache.get("lambda")
#None

I am looking for an explanation for this behaviour. Also, I would like to know if there is a workaround without using def.


Solution

  • The example below fails silently.

    No, it doesn't. The cache.set() call should give you an error like:

    PicklingError: Can't pickle <type 'function'>: attribute lookup __builtin__.function failed
    

    Why? Internally, Django is using Python's pickle library to serialize the value you are attempting to store in cache. When you want to pull it out of cache again with your cache.get() call, Django needs to know exactly how to reconstruct the cached value. And due to this desire not to lose information or incorrectly/improperly reconstruct a cached value, there are several restrictions on what kinds of objects can be pickled. You'll note that only these types of functions may be pickled:

    • functions defined at the top level of a module
    • built-in functions defined at the top level of a module

    And there is this further explanation about how pickling functions works:

    Note that functions (built-in and user-defined) are pickled by “fully qualified” name reference, not by value. This means that only the function name is pickled, along with the name of the module the function is defined in. Neither the function’s code, nor any of its function attributes are pickled. Thus the defining module must be importable in the unpickling environment, and the module must contain the named object, otherwise an exception will be raised.