Emily Emily - 1 month ago 14
Python Question

How do I pickle a dictionary containing a module & class?

I need to assign a module & class to a dictionary key. Then pickle that dictionary to file. Then later, load the pkl file, then import & instantiate the class, based on that dictionary key value.

I've tried this:

import module_example
from module_example import ClassExample

dictionary = {'module': module_example, 'class': ClassExample)


Yet it won't store a reference to module_exmaple.py in the pkl file.

I've tried a workaround of using a string instead of the module & class name. But that's going to lead to a mess if the module name gets refactored or location is changed down the road.

Is there anyway do this directly? Somehow store a reference to the module & class in a dictionary, then later import & instantiate based on that reference?

Answer

This works for single class. If you want to do this in multiple modules and classes, you can extend the following code.

module_class_writer.py

import module_example
from module_example import ClassExample

included_module = ["module_example"]
d = {}
for name, val in globals().items():
    if name in included_module:
        if "__module__" in dir(val):
            d["module"] = val.__module__
            d["class"] = name

#d = {'module': module_example, 'class': ClassExample}

import pickle
filehandler = open("imports.pkl","wb")
pickle.dump(d, filehandler)
filehandler.close()

module_class_reader.py

import pickle
filehandler = open("imports.pkl",'rb')
d = pickle.load(filehandler)
filehandler.close()

def reload_class(module_name, class_name):
    mod = __import__(module_name, fromlist=[class_name])
    reload(mod)
    return getattr(mod, class_name)

if "class" in d and "module" in d: 
    reload(__import__(d["module"]))
    ClassExample = reload_class(d["module"], d["class"])