繁体   English   中英

腌制Python中的类实例字典

[英]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

用我的真实数据集花费了很长时间,我尝试使用picklepickle.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而不是pickledill自己的工作。 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>}
>>> 

如果您正在寻找传统的dumpload ,那也可以。 它也可以与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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM