问题描述
在> Python泡菜:处理更新的类定义,dill
程序包的作者写道:
In the answer to Python pickle: dealing with updated class definitions, the author of the dill
package writes:
好吧,我在github的最新修订版中将此功能添加到了莳萝中.实现起来比我想像的要复杂得多,只需将类定义与pickle和voila序列化即可."
已经安装了dill
并对其进行了修补,对我而言,如何在dill
中实际使用此功能并不明显.有人可以提供一个明确的例子吗?我想腌制类实例并序列化类定义.
Having installed dill
and tinkered with it, it's not obvious to me how to actually use this functionality in dill
. Could someone provide an explicit example? I would like to pickle the class instance and also serialize the class definition.
(我是python的新手,我此功能似乎非常重要,因为当腌制对象时,尽可能地保证可以查看该对象将是一件很棒的事情(可能是由于模拟),以后类定义可能会更改,并且您还没有以一种易于访问的方式跟踪所有更改.)
(I am new to python and I this functionality seems extremely important, as since when pickling an object it would be great to get as close to a guarantee as possible that you could look at the object (could be the result of a simulation) in the future after the class definition may have changed and you haven't kept track of all the changes in an easily accessible way.)
推荐答案
我认为您正在寻找以下功能之一……
I think you are looking for one of the following functionalities…
在这里,我建立一个类和一个实例,然后更改类定义.腌制的类和实例仍然无法腌制,因为dill
腌制默认情况下,该类的源代码…并管理多个类在名称空间中具有相同的名称(它仅通过管理指针来完成类定义的引用.)
Here I build a class, and an instance, and then change the class definition.The pickled class and instance still are unpicklable because dill
picklesthe source code for the class by default… and manages having several classeswith the same name in the namespace (it does this simply by managing the pointerreferences to the class definitions).
Python 2.7.8 (default, Jul 13 2014, 02:29:54)
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import dill
>>>
>>> class Foo(object):
... def bar(self, x):
... return x+self.y
... y = 1
...
>>> f = Foo()
>>> _Foo = dill.dumps(Foo)
>>> _f = dill.dumps(f)
>>>
>>> class Foo(object):
... def bar(self, x):
... return x*self.z
... z = -1
...
>>> f_ = dill.loads(_f, ignore=True)
>>> f_.y
1
>>> f_.bar(1)
2
>>> Foo_ = dill.loads(_Foo)
>>> g = Foo_()
>>> g.bar(1)
2
Pickle会炸毁上面的东西.如果您不希望dill
显式序列化该类并执行pickle
的操作,则可以要求dill
通过引用与dill.dumps(Foo, byref=True)
一起进行腌制.或者,您可以使用ignore=False
(默认值)动态决定忽略新定义的类.
Pickle would blow up on the above. If you don't want dill
to serialize the class explicitly, and to do what pickle
does, then you can ask dill
to pickle by reference with dill.dumps(Foo, byref=True)
. Alternately, you can dynamically decide to ignore the newly-defined class by using ignore=False
(the default).
现在,在以下情况下,我们使用新的类定义,并提取源从对象,然后将其保存到文件.另外,我们可以将源转储到文件中(这里我使用一个临时文件),以便以后可以导入.
Now, in the case below, we work with the new class definition, and extract the sourcefrom the object, then save it to a file. Additionally, we can dump the source to a file (here I use a temporary file) so it can be imported later.
>>> sFoo = dill.source.getsource(Foo)
>>> print sFoo
class Foo(object):
def bar(self, x):
return x*self.z
z = -1
>>> open('myFoo.py', 'w').write(sFoo)
>>>
>>> f = dill.temp.dump_source(Foo, dir='.')
>>> f.name
'/Users/mmckerns/dev/tmpM1dzYN.py'
>>> from tmpM1dzYN import Foo as _Foo_
>>> h = _Foo_()
>>> h.bar(2)
-2
>>> from myFoo import Foo as _SFoo_
>>> _SFoo_.z
>>> -1
>>>
我希望能帮上忙.
这篇关于如何使用莳萝序列化一个类定义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!