[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