If I have a script that defines a class:
script = """
class myClass:
def __init__(self):
self.name = 'apple'
self.color = 'green'
"""
and then exec this script in its own namespace dict:
NS = {}
exec script in NS
and then create an instance of the class and pickle it:
a = NS['myClass']()
import pickle
save = pickle.dumps(a)
Now if I try to unpickle it:
load = pickle.loads(save)
I get the error
AttributeError: 'module' object has no attribute 'myClass'
I gather that this doesn’t work because python doesn’t know where to find myClass in order to rebuild the object. But myClass does exist in the NS dict. Is there a way to tell pickle where to find the class for the object it is loading?
I discovered a solution this. It seems the problem is executing code in a dict prevents python from figuring out where the class is defined. The solution is to create an empty module, execute the code in the module, and then add the module to sys.modules so python knows about it.
Now it is possible to pickle and unpickle an instance of the class: