I think you are looking for one of the following functionalities…
Here I build a class, and an instance, and then change the class definition.
The pickled class and instance still are unpicklable because dill
pickles
the source code for the class by default… and manages having several classes
with the same name in the namespace (it does this simply by managing the pointer
references 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 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 source
from 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
>>>
I hope that helps.
pickle
would: AttributeError: 'Foo' object has no attribute 'y'. circa line 25. Too bad, because it sounded like an instance of magic, and it would make storing dill-ed objects in a database more maintainable. So there is a huge use case. Dill 0.2.7.1, dill settings at default (byref False). I hope it's operator error, but cut and paste is solidly within my skillset. – Locomotion