__getattr__ and pickle
Christian Tismer
tismer at appliedbiometrics.com
Thu Jul 6 12:14:28 EDT 2000
Hmm, have to correct myself a little...
Christian Tismer wrote:
>
> Hi Sean,
...
> > The __getattr__ hook achieves a Delphi-like effect
> > in which attributes of these sub-ordinate objects
> > appear as attributes of the top level object.
> >
> > It seemed like a good idea at the time:-)
>
> Well, I see that your __getattr__ is a little insane.
>
> def __getattr__(self,n):
> if hasattr(self.CurPos,n):
> return getattr(self.CurPos,n)
> else:
> raise PyxieException (
> "No attribute '%s' on xTree or current xNode" % n)
>
> It redirects *every* reading attribute access to the CurPos
> object, so Pickle can't even figure out what your xTree's
> class is. Also, the CurPos object can's be saved with it,
> nothing is accessible.
I was not correct here. According to
http://www.python.org/doc/ref/attribute-access.html
section 3.3.2, the attribute lookup first walks the usual
way, before __getattr__ is invoked.
The problem with your solution is simply this:
(p|cP)ickle does not recreate your curpos object
which you create in __init__ . __init__ is not
called at all.
Now the following happens:
When *ickle tries to reconstruct your object, it is
looking for a __setstate__ property which is not there.
So, __getattr__ is called which then tries to find
self.curpos, which is also not there, causing
__getattr__ to be called, which in turn...... *POFF*.
The easy solution is this:
Give it a __setstate__ method that just creates
the curpos object, like __init__would do.
cheers - chris
file picklish.py:
-------------------------
class magic:
def __init__(self):
self.uh = "oh"
class ughh:
def __getattr__(self, n):
print "getattr called on", n
if hasattr(self.curpos, n):
return getattr(self.curpos, n)
raise AttributeError, n
def __init__(self):
self.curpos = magic()
def __setstate__(self, state):
self.curpos = magic()
import pickle, cPickle
def test(use_cPickle = 0):
pick= (pickle, cPickle) [use_cPickle]
a = ughh()
b = pick.dumps(a)
c = pick.loads(b)
return c
--
Christian Tismer :^) <mailto:tismer at appliedbiometrics.com>
Applied Biometrics GmbH : Have a break! Take a ride on Python's
Kaunstr. 26 : *Starship* http://starship.python.net
14163 Berlin : PGP key -> http://wwwkeys.pgp.net
PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF
where do you want to jump today? http://www.stackless.com
More information about the Python-list
mailing list