Unpickle error -- "object has no attribute ...."
Peter Otten
__peter__ at web.de
Mon Aug 29 05:02:27 EDT 2011
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, see
http://docs.python.org/library/pickle.html#object.__reduce_ex__
By the way, docstrings belong below the def not above:
def f():
"""Explain f() here"""
More information about the Python-list
mailing list