[C++-sig] set python attribute from C++

Gennadiy Rozental rogeeff at gmail.com
Wed Jul 16 22:03:23 CEST 2008


David Abrahams <dave <at> boostpro.com> writes:

> 
> 
> on Tue Jul 15 2008, Gennadiy Rozental <rogeeff-AT-gmail.com> wrote:
> 
> > How can I set object attribute inside the function foo implementation. More
> > generally: how can I get access ot the underlying python object?
> >
> > essentially I want something like this:
> >
> > void foo( A& obj )
> > {
> >    boost::python::object o = get_py_object( obj );
> >    o.attr( "field" ) = 1;
> > }
> 
> I think this works better than the other suggestions:
> 
>   void foo( boost::shared_ptr<A> a )
>   {
>       boost::python::object o(a);
>       o.attr( "field" ) = 1;
>   }
> 
> Please let me know if it works out.

This one does work. But if you switch to intrusive_ptr it;s not anymore ;(. And
this is exactly the scenario I am using. Why is that??

What's more my problem is a bit more complicated. What I ma after is to
initialize object A in it's init method (ideally would be in constructor, but
this is obviously impossible - derived class constructor in python is not even
called yet). So the usage scenario is something like this:

// this may create objects based on pure C++ classes 
// or classes implemented in python.
boost::intrusive_ptr<Base> obj = Factory::create(....); 

obj->init();

init is virtual void init() method of class Base

Now let's say we have class PythonBase inherited from Base, that will serve as a
base class to all python classes. Now inside PythonBase init implementation I
need to do something like:

void
PythonBase::init()
{
   m_object = ... // ?? what should go there
}

Inside init function I want to get a hold of actual python object and cache it.

At the moment I jump through hoops do achieve this.

1. PythonBase is inherited from wrapper<PythonBase>
2. m_object is assigned like this:
        bp::override o = this->get_override( "py_object" );
        return bp::call<bp::object>( o.ptr() );
3. During preprocessing phase i add mixin to all my python classes with method
    def py_object(s):
        return s

It works. But it's quite cumbersome.

Any recomendations?






More information about the Cplusplus-sig mailing list