Unpickle error -- "object has no attribute ...."

luvspython srehtvandy at gmail.com
Mon Aug 29 12:22:52 EDT 2011


On Aug 29, 5:02 am, Peter Otten <__pete... at web.de> wrote:
> luvspython wrote:
> > I have an application that needs to keep a history of the values of
> > several attributes of each of many instances of many classes.  The
> > history-keeping logic is in a helper class, HistoryKeeper, that's
> > inherited by classes like Vehicle in the example below.
>
> > Pickling an instance of Vehicle works, but unpickling fails with:
> >  "Vehicle object has no attribute
> > '_orderedArgNames'"   (_orderedArgNames is an attribute in
> > HistoryKeeper that tells the attributes for which history must be
> > kept.)
>
> > During unpickling, the exception occurs at the 2nd line in the
> > __getattribute__ method:
> >         if item not in object.__getattribute__(self,
> > '_orderedArgNames'):
>
> > FWIW, cPickle fails the same way.
>
> > Below is a stripped-down example that fails in unpickling.
>
> > Can anyone explain why it fails and what I can do to fix it?
>
> By default unpickling an object does *not* invoke its __init__() method;
> instead it creates an instance and then updates the __dict__ attribute of
> that instance. You intercept attribute access with __getattribute__, so to
> get hold of __dict__ you need to know __dict__["_orderedArgNames"] first, i.
> e. you run into a bootstrap problem.
>
> To fix the error I'd try special-casing "__dict__"
>
> def __getattribute__(self, item, ...):
>     if item == "__dict__":
>         return super(HistoryKeeper, self).__getattribute__(item)
>     ...
>
> or making _orderedArgNames a class attribute:
>
> class HistoryKeeper(object):
>     def __init__(self, orderedArgs):
>         for arg, value in orderedArgs.items():
>             if arg != 'self':
>                 self.Set(arg, value)
>     ...
>
> class Vehicle(HistoryKeeper):
>     _orderedArgNames = "tag", "make", "model"
>     ...
>
> If that doesn't work out you can write your own __reduce_ex__() method to
> customise pickling, seehttp://docs.python.org/library/pickle.html#object.__reduce_ex__
>
> By the way, docstrings belong below the def not above:
>
> def f():
>     """Explain f() here"""- Hide quoted text -
>
> - Show quoted text -

THANK YOU!  Special-casing "__dict__" did the trick.  Not sure I'd
have ever figured that out, which leads to a different question:

I can figure out most things, though perhaps very slowly and
painfully, if I can trace through code.  I use WingIDE (love it), but
the execution
of the C code is of course hidden, which helped stymie on this
problem.  Is there another tool y'all might use and you can suggest
that deals with that problem and would have helped me with this case?
Or is one's ability to figure out this sort of problem largely
dependent on really understanding the system's internals?



More information about the Python-list mailing list