Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #12398

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

From Peter Otten <__peter__@web.de>
Newsgroups comp.lang.python
Subject Re: Unpickle error -- "object has no attribute ...."
Followup-To comp.lang.python
Date 2011-08-29 11:02 +0200
Organization None
Message-ID <j3fkii$umf$1@solani.org> (permalink)
References <45c360d7-899d-4496-88dc-2112979f36ab@eb1g2000vbb.googlegroups.com>

Followups directed to: comp.lang.python

Show all headers | View raw


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"""

Back to comp.lang.python | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

Unpickle error -- "object has no attribute ...." luvspython <srehtvandy@gmail.com> - 2011-08-28 17:00 -0700
  Re: Unpickle error -- "object has no attribute ...." Peter Otten <__peter__@web.de> - 2011-08-29 11:02 +0200
    Re: Unpickle error -- "object has no attribute ...." luvspython <srehtvandy@gmail.com> - 2011-08-29 09:22 -0700
      Re: Unpickle error -- "object has no attribute ...." Chris Angelico <rosuav@gmail.com> - 2011-08-30 04:27 +1000
      Re: Unpickle error -- "object has no attribute ...." Peter Otten <__peter__@web.de> - 2011-08-30 16:21 +0200

csiph-web