If I have a script that defines a class:
script = \"\"\"
class myClass:
def __init__(self):
self.name = \'apple\'
self.color = \'green\'
You can actually go one step further, and have the object reconstruct itself into whatever type you want.
import pickle
import copy_reg
class myClass(object):
def __init__(self):
self.apple = 'banana'
class otherclass(object):
def __init__(self):
self.apple = 'existential woe'
def pickle_an_object(o):
print "pickling %s" % str(o)
return otherclass, (o.apple,)
copy_reg.pickle(myClass, pickle_an_object)
foo = myClass()
s = pickle.dumps(foo)
del myClass
del otherclass
class otherclass(object):
def __init__(self, appletype):
self.apple = 'not %s' % appletype
o2 = pickle.loads(s)
print o2.apple
The basic idea is that you pack your class into a "trojan horse" of sorts, where its reconstruction causes an instantiation of a different class from what it originally was.
It does not matter what the otherclass
on the pickling side contains. All that matters is that it exist at the same module path as the "destination" class - pickle
is just putting a string representation of the module name into the serialized stream.
So, to break down what's happening in the above code in detail:
myClass
. This can be done via copy_reg
or the __reduce_ex__
function.otherclass
" (which is a dummy. You do not need the "real" contents of otherclass
on the pickling side, because all that goes into the pickle is the module/class name).otherclass
exists.otherclass
is instantiated with the data from the tuple returned by the custom pickling function.Python can be pretty powerful!