[C++-sig] Re: wrapping complex attributes

Mike Rovner mike at bindkey.com
Wed Nov 13 23:31:58 CET 2002


David,

Thanks for your invaluable help. You fast answers greatly smooth BPL leaning
curve.

As you suggested many times before I first experimented with pure Python
code first.

So I have two working variants of what I want:

1) with implicit self

class cTcn:
  # suppose it's some c++ member functions
  def getX(self,n): print 'getX(%s)'%n
  def delX(self,n): print 'delX(%s)'%n
  def newX(self,n): print 'newX(%s)'%n
  def getXall(self):print '[getXall()]'

  def getY(self,n): print 'getY(%s)'%n
  def delY(self,n): print 'delY(%s)'%n
  def newY(self,n): print 'newY(%s)'%n
  def getYall(self):print '[getYall()]'

  def getZ(self,n): print 'getZ(%s)'%n
  def delZ(self,n): print 'delZ(%s)'%n
  def newZ(self,n): print 'newZ(%s)'%n
  def getZall(self):print '[getZall()]'

  # now I want 3 more members
  def __init__(self):
    self.x=tcn_helper(self.getX, self.delX, self.newX, self.getXall)
    self.y=tcn_helper(self.getY, self.delY, self.newY, self.getYall)
    self.z=tcn_helper(self.getZ, self.delZ, self.newZ, self.getZall)

class tcn_helper:
  def __init__(self,get,del_,new,all):
    self.__getitem__=get
    self.__delitem__=del_
    self._newitem=new
    self.__iter__=all
  def new(self,n):    return self._newitem(n)

usage:
t=cTcn()
t.x['a']
>>> getX(a)

2) with explicit self

class cTcn:
  def getX(self,n): print 'getX(%s)'%n
  def delX(self,n): print 'delX(%s)'%n
  def newX(self,n): print 'newX(%s)'%n
  def getXall(self):print '[getXall()]'

  def getY(self,n): print 'getY(%s)'%n
  def delY(self,n): print 'delY(%s)'%n
  def newY(self,n): print 'newY(%s)'%n
  def getYall(self):print '[getYall()]'

  def getZ(self,n): print 'getZ(%s)'%n
  def delZ(self,n): print 'delZ(%s)'%n
  def newZ(self,n): print 'newZ(%s)'%n
  def getZall(self):print '[getZall()]'

class Tcn(cTcn):
  def __init__(self):
    self.x=tcn_helper(self,cTcn.getX, cTcn.delX, cTcn.newX, cTcn.getXall)
    self.y=tcn_helper(self,cTcn.getY, cTcn.delY, cTcn.newY, cTcn.getYall)
    self.z=tcn_helper(self,cTcn.getZ, cTcn.delZ, cTcn.newZ, cTcn.getZall)

class tcn_helper2:
  def __init__(self,base,get,del_,new,all):
    self.base=base
    self.__getitem__=get
    self.__delitem__=del_
    self._newitem=new
    self.__iter__=all
  def __getitem__(self,n): return self._getitem(self.base,n)
  def __delitem__(self,n): self._delitem(self.base,n)
  def __iter__(self): return self._iter(self.base)
  def new(self,n):    return self._newitem(self.base,n)

usage:
t=cTcn()
t.x['a']

>>> getX(a)

Now I have some problems translating that code to C++.

"David Abrahams" <dave at boost-consulting.com> wrote in message
news:uadkes7p4.fsf at boost-consulting.com...
> "Mike Rovner" <mike at bindkey.com> writes:
>
> > Here is another dark corner:
> >
> > I have a complex C++ object:
> >
> > class Heavy {
> >   void SetX(const char *name, const T1& val);
> >   T1 GetX(const char *name);
> >   void DelX(const char *name);
> >   Iter<T1> EnumX();
> >
> >   void SetY(const char *name, const T2& val);
> >   T2 GetY(const char *name);
> >   void DelY(const char *name);
> >   Iter<T2> EnumY();
> >
> >   void SetZ(const char *name, const T3& val);
> >   T3 GetZ(const char *name);
> >   void DelZ(const char *name);
> >   Iter<T3> EnumZ();
> > }
> >
> > It seems natural to expose class Heavy with 3 attributes: x,y and z
which
> > will behave like dictionaries.
> > How to do that?
>
> Use the add_property member of class_<>:

'add_property' is not sufficient as it suggest only get/set. I want to use
'setattr' instead.

class_<Heavy>("Tcn")
  .setattr("x", class_<tcn_helper>
    .def("__getitem__", &Heavy::GetX,
return_value_policy<reference_existing_object>() )  // line 138
    () )
  .setattr("y", class_<tcn_helper>
    .def("__getitem__", &Heavy::GetY, return_value_policy<...>() )
    () )
  .setattr("z", class_<tcn_helper>
    .def("__getitem__", &Heavy::GetZ, return_value_policy<...>() )
    () )
  ;

However I have a problem with passing 'self' and designing tcn_helper class.

With 'empty' tcn_helper class I got gcc error:
PyTcn.cpp:138: no matching function for call to `
   boost::python::class_<tcn_helper, boost::python::detail::not_specified,
   boost::python::detail::not_specified,
boost::python::detail::not_specified>
   ::def(const char[2], <unknown type>,

boost::python::return_value_policy<boost::python::reference_existing_object,
   boost::python::default_call_policies>)'

I even don't understand why &Heavy::GetX is unknown.
Can you help me?

Mike








More information about the Cplusplus-sig mailing list