I'm playing around with class inheritances and I'm stuck on how to pickle data in the class dictionary.
If dump only the dictionary part of self, when I load the dictionary back to self, self takes on a dict type instead of a class. But if I pickle the whole class then I get an error.
pickle.PicklingError: Can't pickle <class 'main.model'>: it's not the same object as main.model
import os, pickle
class model(dict):
def __init__( self ):
pass
def add( self, id, val ):
self[id] = val
def delete( self, id ):
del self[id]
def save( self ):
print type(self)
pickle.dump( dict(self), open( "model.dict", "wb" ) )
def load( self ):
print 'Before upacking model.dic, self ==',type(self)
self = pickle.load( open( "model.dict", "rb" ) )
print 'After upacking model.dic, self ==',type(self)
if __name__ == '__main__':
model = model()
#uncomment after first run
#model.load()
#comment after first run
model.add( 'South Park', 'Comedy Central' )
model.save()
If all you want to do is have a class called model that is a subclass of dict and can be properly pickled and unpickled back to an object that is also of type model then you don't have to do anything special. The methods you have defined in your example to add and delete are unnecessary you can just do them directly on model instances as you would do with any other dict. The save and load methods can be done using the pickle module instead of on the class itself.
code
import pickle
class model(dict):
pass
a = model()
pickled = pickle.dumps(a)
b = pickle.loads(pickled)
print type(a), a
print type(b), b
output
<class '__main__.model'> {}
<class '__main__.model'> {}
below is another version which is maybe more in line with what you were trying to achieve. But you should NOT do things this way. The load method is weird so is the save. I put the code below to show it can be done but not really something you want to do because it will end up being very confusing.
another version (don't do this)
import pickle
class model(dict):
def save(self):
with open("model.dict", "wb") as f:
pickle.dump(self, f)
def load(self):
with open("model.dict") as f:
return pickle.load(f)
#comment after first run
test = model()
test['South Park'] = 'Comedy Central'
test.save()
print type(test), test
#uncomment after first run
test2 = model().load()
print type(test2), test2
Further Reading
A great example of a subclass of dict that is is picklable is collections.OrderedDict . It is part of the python standard library and is implemented in python so you can have a peak at the source. The definition is 172 lines of code so it's not too much code to look through. It also had to implement the __reduce__
method to achieve pickling because it has information about the order of items that also needs to be pickled and unpickled. It's a good example of why you might want to make your own subclass of dict, it adds the very useful feature of respecting the order of values added to the dict.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.