如果我有定义一个类的脚本:
script = """ class myClass: def __init__(self): self.name = 'apple' self.color = 'green' """
然后在其自己的命名空间dict中执行此脚本:
NS = {} exec script in NS
然后创建该类的实例并将其腌制:
a = NS['myClass']() import pickle save = pickle.dumps(a)
现在,如果我尝试解开它:
load = pickle.loads(save)
我得到错误
AttributeError: 'module' object has no attribute 'myClass'
我认为这不起作用,因为python不知道在哪里可以找到myClass来重建对象。但是myClass确实存在于NS字典中。有没有办法告诉pickle在哪里为正在加载的对象找到类?
我发现了一个解决方案。看来问题是在dict中执行代码会阻止python弄清楚类的定义位置。解决方案是创建一个空模块,执行模块中的代码,然后将该模块添加到sys.modules中,以便python知道。
script = """ class myClass: def __init__(self): self.name = 'apple' self.color = 'green' """ import imp, sys moduleName = 'custom' module = imp.new_module(moduleName) exec script in module.__dict__ sys.modules[moduleName] = module
Now it is possible to pickle and unpickle an instance of the class:
import pickle a = module.myClass() s = pickle.dumps(a) b = pickle.loads(s)