如何在一个文件(Python文件1)中对包含类实例的字典对象进行pickle
操作,并在另一个文件(Python文件2)中使用pickle.load
加载?
我有一个由多个文件组成的巨大复杂数据集,我创建了一个类来存储所有的属性。我创建了一个字典来存储所有的样本和属性。键 = 样本,值 = 包含属性的类的实例。下面是一个示例:
#Python File 1import randomclass Storage: def __init__(self,label,x,y): self.label = label; self.x = x; self.y = y def get_x(self): return(self.x) def get_y(self): return(self.y)D_var_instance = {}L = ["A","B","C"]for var in L: D_var_instance[var] = Storage(label=var,x=random.random(),y=random.random())print(D_var_instance["A"])#<__main__.Storage instance at 0x102811128>print(D_var_instance["A"].get_x())#0.193517721574
使用我的真实数据集创建这个过程花费了很长时间,我尝试使用pickle
和pickle.dump
来保存字典对象,但它不起作用:
#Python File 1import picklepickle.dump(D_var_instance,open("/path/to/dump.txt","w"))pickle.dump(Storage, open("/path/to/storagedump.txt","w"))
我尝试在另一个Python文件中使用以下代码加载:
#Python File 2import pickleStorage = pickle.load(open("/path/to/storagedump.txt","r"))D_var_instance = pickle.load(open("/path/to/dump.txt","r"))
得到了这个错误:
AttributeError: 'module' object has no attribute 'Storage'
回答:
这里的问题可以通过这个Stack Overflow帖子这里完美解释
最终,这里发生的事情是,当你对你的实例进行pickle操作时,你必须能够适当地引用你从哪里进行pickle操作的模块。
因此,为了说明这一点,可以这样做(后续将进行解释):
storage.py
class Storage(object): pass
foo.py
import picklefrom storage import StorageD_var_instance = {}L = ["A","B","C"]for var in L: D_var_instance[var] = Storage(label=var,x=random.random(),y=random.random())pickle.dump(D_var_instance, open("/path/pickle.txt", "wb"))
boo.py
D_var_instance = pickle.load(open("/path/pickle.txt", "rb"))
所以,当你在foo中编写你的pickle时,你的引用现在将是storage.Storage
。当你进入一个完全不同的模块(boo.py)并尝试取消pickle时,这里发生的事情是你试图加载与你所在位置无法工作的模块相关的引用。
现在解决这个问题的方法有很多种。由于我将所有内容都结构在同一级别,你实际上不需要导入任何东西,它应该可以工作!
然而,如果你碰巧在同一个模块中拥有你的类和pickle写入,就像你所做的那样,那么你将不得不导入在boo.py
中包含该代码的模块
我建议你查看我链接的SO帖子里提供的两个选项,看看哪个满足你的需求。但那应该是你的解决方案。
从iPython运行这个脚本会得到:
ipython boo.py{'A': <storage.Storage instance at 0x1107b77e8>, 'C': <storage.Storage instance at 0x1107b7680>, 'B': <storage.Storage instance at 0x1107b7908>}