Pickle: AttributeError: 'module' object has no attribute

I found many threads about this, but the problem with all of them is the namespace. My problem has nothing to do with the namespace.

A small example:

import cPickle as pickle from uncertainties import Variable class value(Variable): def __init__(self, args, showing=False): self.show = showing Variable.__init__(self, args[0], args[1]) val = value((3,1), True) print val.nominal_value, val.std_dev(), val.show fobj = file("pickle.file", "w") pickle.dump(val, fobj) fobj.close() fobj = file("pickle.file", "r") val = pickle.load(fobj) fobj.close() print val.nominal_value, val.std_dev(), val.show 

Result of this code:

 3.0 1.0 True 3.0 1.0 --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) /usr/lib/python2.7/dist-packages/IPython/utils/py3compat.pyc in execfile(fname, *where) 173 else: 174 filename = fname --> 175 __builtin__.execfile(filename, *where) /home/markus/pickle.py in <module>() 19 val = pickle.load(fobj) 20 fobj.close() ---> 21 print val.nominal_value, val.std_dev(), val.show AttributeError: 'value' object has no attribute 'show' 

The namespace is the same when pickled and scattered. All uncertainties.Variable attributes are restored - only my added one “show” is skipped.

+4
source share
1 answer

uncertainties.Variable() class uses the __slots__ attribute to save memory. As a result, in order to be legible, it must define the __getstate__ method (see Why am I having an error regarding my class defining __slots__ when trying to sort an object? ).

If you need to add your additional attributes, you will have to override this __getstate__ method. Declaring your additional attributes in your own __slot__ attribute is probably also a good idea:

 from uncertainties import Variable class value(Variable): __slots__ = ('show',) # only list *additional* slots def __init__(self, args, showing=False): self.show = showing super(value, self).__init__(args[0], args[1]) def __getstate__(self): obj_slot_values = {} for cls in type(self).mro(): obj_slot_values.update((k, getattr(self, k)) for k in getattr(cls, '__slots__', ())) # Conversion to a usual dictionary: return obj_slot_values 

This new __getstate__ is required because the Variable.__getstate__ assumes that there will be only one __slots__ attribute, while each class in the MRO can have one.

This is really a limitation of the library of uncertainties ; I submitted a migration request that addresses this and will eliminate the need to override the __getstate__ method in a subclass.

+6
source

All Articles