[C++-sig] Re: Pickling object from nested class

Ralf W. Grosse-Kunstleve rwgk at yahoo.com
Fri Oct 24 20:16:53 CEST 2003


Hi Nikolay,

I thought you can only pickle objects of top-level classes:

http://www.python.org/doc/current/lib/node64.html

> The following types can be pickled:
>   ...
>   - classes that are defined at the top level of a module

% cat outer_inner.py 
class outer:

  class inner:
    pass

% cat pickle_inner.py
import outer_inner
import pickle

i = outer_inner.outer.inner()
s = pickle.dumps(i)
j = pickle.loads(s)

% python pickle_inner.py
Traceback (most recent call last):
  File "pickle_inner.py", line 6, in ?
    j = pickle.loads(s)
  File "/usr/lib/python2.2/pickle.py", line 985, in loads
    return Unpickler(file).load()
  File "/usr/lib/python2.2/pickle.py", line 596, in load
    dispatch[key](self)
  File "/usr/lib/python2.2/pickle.py", line 766, in load_inst
    klass = self.find_class(module, name)
  File "/usr/lib/python2.2/pickle.py", line 823, in find_class
    klass = getattr(mod, name)
AttributeError: 'module' object has no attribute 'inner'

I cannot explain why this fails only at pickle.loads() while your example seems
to fail already at the dump stage. But anyway, I'd not expect pickling of
nested classes to work.

I'd try wrapping outer.inner as outer_inner:

% cat outer_inner.py
class outer_inner:
  pass

class outer:

  inner = outer_inner

This makes my little example work.

Ralf
 
--- Nikolay Mladenov <nickm at sitius.com> wrote:
> Here it is:
> 
> cpp:
> 
> struct OBJ{
> public :
>     struct PROP{
>         PROP(int i=0):p(i){}
>         int p;
>         operator int ()const{return p;}
>     };
>     OBJ(int p=0):prop(p){}
>     PROP prop;
>     operator int ()const{return prop.p;}
> };
> 
> #include <boost/python.hpp>
> 
> using namespace boost::python;
> 
> template <class T>
> struct pickle_suite_: pickle_suite
> {
>     static tuple getinitargs(const T &t){
>         return make_tuple((int)t);
>     }
> };
> 
> BOOST_PYTHON_MODULE(inner)
> {
>     scope s(
>         class_<OBJ>("OBJ", init<optional<int> >())
>             .def_pickle(pickle_suite_<OBJ>())
>         );
>     class_<OBJ::PROP> ("PROP", init<optional<int> >())
>         .def_pickle(pickle_suite_<OBJ::PROP>());
>     
> }
> //////////////////////////////////////
> 
> 
> 
> 
> py:
> 
> import inner
> from sys import stdout as out
> from pickle import dump
> dump(inner.OBJ.PROP(),out)
> #   ----------
> #   stacktrace
> #   ----------
> #dump(inner.OBJ(), out) works fine


__________________________________
Do you Yahoo!?
The New Yahoo! Shopping - with improved product search
http://shopping.yahoo.com




More information about the Cplusplus-sig mailing list