[英]Pickle a dictionary of class instances in Python
如何在一个文件(Python文件1)中pickle
包含类实例的字典对象,在另一个文件(Python文件2)中pickle.load
?
我有一个由几个文件组成的庞大的复杂数据集,并且创建了一个用于存储所有属性的类。 我制作了一个字典来存储所有示例和属性。 键=样本,值=包含属性的类的实例。 下面的例子:
#Python File 1
import random
class 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 1
import pickle
pickle.dump(D_var_instance,open("/path/to/dump.txt","w"))
pickle.dump(Storage, open("/path/to/storagedump.txt","w"))
我尝试使用以下代码加载另一个Python文件:
#Python File 2
import pickle
Storage = 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'
您可以使用dill
而不是pickle
来dill
自己的工作。 dill
泡菜类定义以及类实例(而不是像pickle
那样通过引用)。 因此,除了import dill as pickle
之外,您无需执行任何其他操作。
为了模拟在另一个文件中的工作,我将在字典中构建一个类,一些类实例,然后删除除腌制字符串以外的所有内容。 您可以从那里重新构成。
>>> class Foo(object):
... def __init__(self, x):
... self.x = x
...
>>> d = dict(f=Foo(1), g=Foo(2), h=Foo(3))
>>>
>>> import dill
>>> _stored_ = dill.dumps(d)
>>>
>>> del Foo
>>> del d
>>>
>>> d = dill.loads(_stored_)
>>> d['f'].x
1
>>> d['g'].x
2
>>> d['h'].x
3
>>> dill.dump_session()
我完成了dump_session
,将解释器中的所有内容腌制到一个文件中。 然后,在新的python会话中(可能在其他计算机上),您可以从上次中断的地方开始。
>>> import dill
>>> dill.load_session()
>>> d
{'h': <__main__.Foo object at 0x110c6cfd0>, 'g': <__main__.Foo object at 0x10fbce410>, 'f': <__main__.Foo object at 0x110c6b050>}
>>>
如果您正在寻找传统的dump
和load
,那也可以。 它也可以与ipython
一起ipython
。
通过此处的SO帖子可以完美地解释这里的问题
最终,这里发生的事情是,当您对实例进行酸洗时,必须能够根据从何处酸洗模块来适当地引用模块。
因此,显示一些代码来说明这一点。 您可以执行此操作(说明如下):
storage.py
class Storage(object):
pass
foo.py
import pickle
from storage import Storage
D_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编写泡菜时,您的引用将是storage.Storage
。 当您进入一个完全不同的模块(boo.py)并尝试释放时,这里发生的是您正在尝试引用某个模块,该模块无法从您正在使用的模块开始工作。
现在可以以不同的方式来解决此问题。 由于我将所有结构都组织在同一级别,因此实际上您不需要导入任何东西,它应该可以工作!
但是,如果您碰巧像在同一个模块中编写类和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>}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.