Overriding Dictionary Object

A

Adonis

I am subclassing the dict object, and having it serialize itself to disk for
later access, but I am having some trouble with accessing the self._filename
attribute, when the object is first created it functions fine, but when I
access it on a later time, self._filename is not present, how can I go about
this knowing that when objects are serialized they are not initialized on
subsequent access? I was under the impression that everything in an objects
scope was serialized by pickle, or is my assumption wrong?

Any help is greatly appreciated.

Adonis

----

Error:
File "data.py", line 9, in _sync
data = open(self._filename, 'w')
AttributeError: 'Driver' object has no attribute '_filename'


Code:
import cPickle

class Driver(dict):
def _sync(self):
data = open(self._filename, 'w')
cPickle.dump(self, data, -1)
data.close()

def __delitem__(self, key):
dict.__delitem__(self, key)
self._sync()

def __setitem__(self, key, value):
dict.__setitem__(self, key, value)
self._sync()

def __init__(self, filename="appweb.data"):
dict.__init__(self)

if os.path.exists(filename):
data = open(filename)
self = cPickle.load(data)
data.close()

self._filename = filename
 
C

Christopher T King

I am subclassing the dict object, and having it serialize itself to disk for
later access, but I am having some trouble with accessing the self._filename
attribute, when the object is first created it functions fine, but when I
access it on a later time, self._filename is not present, how can I go about
this knowing that when objects are serialized they are not initialized on
subsequent access? I was under the impression that everything in an objects
scope was serialized by pickle, or is my assumption wrong?

Your assumption is correct -- the problem is elsewhere in your code: the
line 'self = cPickle.load(data)' doesn't do what you think it does -- this
only sets the local variable 'self' to the object returned by load(), not
change the object itself. Hence, self._filename is setting the attribute
of a soon-to-be-out-of-scope object, not the current object.

To get the effect you want, you would have to implement the __new__ method
of the object. The __new__ method is supposed to return a new,
uninitialized instance of the class, but you can have it return an old
instance instead (though you must make sure it doesn't get initialized).

However, I suggest you try other ways of accomplishing your goal. Writing
the entire dictionary to disk every time one of its values is changed is
very inefficient, and will also cause obscure bugs to appear, assuming
it's used in a threaded context (e.g. a web server). The dbhash module
provides an efficient, thread-safe mechanism that does the same thing as
your class:

import dbhash

data = dbhash.open('appweb.data','cl') # 'cl' means create if necessary,
# and use automatic locking

data['foo']='bar' # set a new value
print data['apple'] # retrieve an old value
data.close() # all done here
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top