shelf membership

Peter Otten __peter__ at web.de
Sun Apr 1 05:20:45 EDT 2007


Aaron Brady wrote:

> can you shelve objects with membership?
> 
> this gives you:
> 
> TypeError: object does not support item assignment
> dict 0 True
> Exception exceptions.TypeError: 'object does not support item assignment' 
> in  ignored
> 
> > ignored is a bit mysterious.  tx in advance.
> 
> from shelve import *
> class MyShelf(DbfilenameShelf):
>           def __init__(self, filename, flag='c', protocol=None, 
> writeback=False, binary=None):
>                   self.__dict__['ready']=False
>                   DbfilenameShelf.__init__(self, filename, flag, protocol, 
> writeback, binary)
>                   self.ready=True
>           def __setattr__(self,name,value):
>                   if not self.ready:
>                           self.__dict__[name]=value
>                   else:
>                           print name, value, self.ready
>                           self.__dict__[name]=value
>                           DbfilenameShelf.__setitem__(self,name,value)
> 
> def open(filename, flag='c', protocol=None, writeback=False, binary=None):
>       return MyShelf(filename, flag, protocol, writeback, binary)

The root cause of your problems is that you are mixing two namespaces: that
of the shelved items and that used internally by DbfilenameShelf to
implement the shelving functionality.

While the cleanest approach is to not do it, you can make such a mix work
in /some/ cases if you give precedence to the "implementation namespace".
This requires that you pass by any implementation attributes

pass_through_attributes = [...]
def __setattr__(self, name, value):
    if name in pass_through_attributes:
        self.__dict__[name] = value # *
    else:
        # do whatever you like

(*) Assuming that DbfilenameShelve is an oldstyle class and does not itself
implement a __setattr__() method.

>From your error message one can infer that pass_through_attributes must
contain at least the name "dict"; for a complete list you have to inspect
the Dbfilename source code.

An approach that is slightly more robust is to wrap DbfilenameShelf -- make
it an attribute of MyShelf -- and pass the relevant method calls to the
attribute.

Peter



More information about the Python-list mailing list