开发者

Boost.Python: Grab 'self' from member function

Class member functions in Python have to explicitly declare a self parameter which represents the class instance. Is there a way to get a hold of self from C++, by using Boost?

class FooBar
{
  public:
    void func() {
    }
};

// A wrapper for the above class
struct FooBar_W
    : public FooBar
{
    void func(boost::python::object self) {
        // Do smth with `self`
        FooBar::func();
    } 
};

BOOST_PYTHON_WRAPPER(module)
{
开发者_如何学Go    class_<FooBar_W>("FooBar")
        .def("func", &FooBar_W::func)
     ;
}

Edit: Why I want self

I'm writing an event system for my game and I want the scripter to be able to define new types of events. I need a way to distinguish between different types of events. My Python code looks something like this:

class KeyboardEvent(Event): 
    pass

def onKeyPress(event):
    pass

# EventManager is defined in C++
em = EventManager()

# This is how I register a new callback function with the manager
# The `onKeyPress` function will now only be notified when an event
# of type `KeyboardEvent` occurs. (Notice that I passed the actual
# class object, and not an instance of it.)
em.addEventHandler(KeyboardEvent, onKeyPress)

# This is how I queue new events
# (This time I pass an instance of an event, not a type of event.)
em.queueEvent(KeyboardEvent())

The manager needs to figure out what type of event I just queued. I figured I should do something like type(event).__name__ (but in C++, not in Python). This way I can determine the type and know which functions to notify of the event. I want to get self in C++ so I can access the __name__ attribute of its type.

I could have the scripter manually edit a new field that holds the name of the type, but why? That information already exists (the __name__ attribute) so why duplicate it, but more importantly, why bother the scripter with implementation details?


It's doable. The way to do it can be found in the link below; that page documents one way (the old way) to expose pure virtual functions. The example can be adapted to other needs, though.
> http://wiki.python.org/moin/boost.python/OverridableVirtualFunctions#Pure_Virtual_Functions


it's an old question, but for those who are still looking for a reasonably simple solution:

Static function (non-member as well as member) receive a const boost::python::object& self as the first argument. So you can do the following:

class FooBar
{
  public:
    static void func(const boost::python::object self) {
        FooBar& thisref = boost::python::extract<FooBar&>(self)();
        // use self as well as thisref
    }
};

};

BOOST_PYTHON_WRAPPER(module)
{
    class_<FooBar>("FooBar")
        .def("func", &FooBar::func)
     ;
}


self in python is this in C++.

You can think of the line FooBar::func(); as translating to static_cast<FooBar*>(this)->func()

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜