changes to shelf items fail silently?

eichin at metacarta.com eichin at metacarta.com
Tue Mar 18 18:08:14 EST 2003


> Am I skipping over some important assumption without realizing it?

I think the distinction is that in any other context, and any other
use of that *syntax*, you don't especially care that it is a
reference, because if you mutate the object, the dict still contains a
reference to the mutated object.  With shelf, you're *not* mutating
the object, you're mutating a temporary copy.  

Also: 

> of a key-value database on disk (dbm) and a generic object
> serialization protocol (pickle).

While the __doc__ does say that, it isn't clear why that should cause
this effect; serialization is just "how it is stored", and doesn't
inherently imply "so you only get temporaries out".

> *chuckle*  Good point.  (I assume you also don't need multiple
> users reading and writing simultaneously.)

Right - another way of describing my use case is "single daemon that
does stuff, keeps information about it in-memory in a dict - great
prototype, now it needs to be restartable."  One could just pickle the
whole dict and write it out at every commit point, but (1) shelve
looks more efficient (2) using shelve is far easier to write
[literally, import it, and then use shelve.open() instead of {} as an
initializer.]

> I don't know Perl, as it happens.  What's a tied hash?

A perl hash is basically a python dict;  the main difference is that
it can hold only "scalars" (numbers, strings, references; not other
hashes, or lists.)

A "tied" hash is one that has an associated Class with
a standard set of methods (FETCH, DELETE, STORE, etc.) that get called
when the relevant thing is done.  Defining __getitem__/__setitem__ has
pretty much the same effect in python.  

Hmm.  I suspect it's actually harder to do this in perl (you pretty
much have to take the wrapper approach) since the only way to put
higher level objects in *is* to put in references - so that would have
led me to what the problem was much more quickly...

(On a side note, it occurs to me that the dict structure *isn't*
arbitrarily deep, it's only a dict-of-dicts, so I could instead
shelve.open each subdict.  Then at startup, scan the values and open
all of the subshelves explicitly.  A little tricky but may end up more
efficient once the subdicts start getting large (ie. that's the way to
handle it if the overhead of repickling on inserts gets too big.))

> Now, what about shelved foobar.wombat objects?  Which of their
> methods should cause commits?

Mmm, throw an exception if they don't "conform" to some interface.
The reason I went down this path isn't that it silently discarded the
changes, after all; I'd have been happy if it had non-silently told me
(perhaps by having the references be non-mutable and cause exceptions
to be thrown on changes, for example.)




More information about the Python-list mailing list