Okay, I'm thrashing my way through this the hard way, so if I'm
completely misusing shelve, let me know.
At any rate, let's say I define a class:
---
>>> class Foo:
... def __init__(self, bar):
... self.Bar = bar
---
Why? 'Cause it's convenient to initialize at creation. So we open a
shelf and shelve it away:
---
>>> d = shelve.open('foobar')
>>> x = Foo(12)
>>> x
<Foo instance at 814f510>
>>> x.Bar
12
>>> d['bar']=x
>>> d.keys()
['bar']
---
Okey doke. Now try to fetch it from the shelf:
---
>>> y = d['bar']
Traceback (innermost last):
File "<stdin>", line 1, in ?
File "/usr/local/lib/python/shelve.py", line 56, in __getitem__
return pickle.Unpickler(f).load()
File "/usr/local/lib/python/pickle.py", line 367, in load
self.dispatch[key](self)
File "/usr/local/lib/python/pickle.py", line 435, in load_inst
value = apply(klass, args)
TypeError: not enough arguments
---
Seems simple; the object is fetched, a new instance is created,
__init__ is called, and __init__ bitches 'cause no initialization
arguments (save self, of course) are given.
Now this may very well be correct, but why does it seem broken to
me? Comments?
FWIW-- start a new session, define:
---
>>> class Foo: pass
---
And try to unshelve the object shelved above, and it still
chokes as above.
-- Cerebus <tmi...@ims.advantis.com>
"1.4beta1, BTW. Under Linux 2.0.0."
No, but you may want to read up on the __doc__ string for the
pickle.py module, upon which shelve is built.
[...]
> Seems simple; the object is fetched, a new instance is created,
> __init__ is called, and __init__ bitches 'cause no initialization
> arguments (save self, of course) are given.
>
> Now this may very well be correct, but why does it seem broken to
> me? Comments?
Pickle has a documented restriction that if a pickled instance has a
constructor that requires arguments, it should define a method
__initargs__() that returns the arguments to be provided at
unpickling time. See the above mentioned __doc__ string.
> FWIW-- start a new session, define:
>
> ---
> >>> class Foo: pass
> ---
>
> And try to unshelve the object shelved above, and it still
> chokes as above.
Hmm, strange -- can't seem to reproduce this. Are you sure it chokes
in the same way?
--Guido van Rossum (home page: http://www.python.org/~guido/)
We all get bit by this at some point! Since your __init__ has
argument(s) besides self you need to supply a method, called getinitargs,
which the pickler will call to store the value(s) for any initial
argument(s). For the example you have below you'll just need
def __getinitargs__ (self):
return (self.Bar,) # notice I'm returning a tuple
nick
>
> Okay, I'm thrashing my way through this the hard way, so if I'm
> completely misusing shelve, let me know.
>
> Seems simple; the object is fetched, a new instance is created,
> __init__ is called, and __init__ bitches 'cause no initialization
> arguments (save self, of course) are given.
>
> Now this may very well be correct, but why does it seem broken to
> me? Comments?
>
> FWIW-- start a new session, define:
>
> ---
> >>> class Foo: pass
> ---
>
> And try to unshelve the object shelved above, and it still
> chokes as above.
>
> -- Cerebus <tmi...@ims.advantis.com>
> "1.4beta1, BTW. Under Linux 2.0.0."
>
---------------------------
Nick Seidenman
Science Applications International Corporation