Boost.Python:从成员函数中获取“self”

2 投票
3 回答
896 浏览
提问于 2025-04-16 22:32

在Python中,类的成员函数必须明确声明一个叫做self的参数,这个参数代表了类的实例。有人想知道,是否可以通过使用Boost库在C++中获取self

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)
{
    class_<FooBar_W>("FooBar")
        .def("func", &FooBar_W::func)
     ;
}

补充说明:我为什么需要self

我正在为我的游戏编写一个事件系统,想让脚本编写者能够定义新的事件类型。我需要一种方法来区分不同类型的事件。我的Python代码大致是这样的:

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())

管理器需要弄清楚我刚刚排队的事件是什么类型。我想我应该在C++中做类似type(event).__name__的事情。这样我就可以确定事件的类型,并知道应该通知哪些函数。我想在C++中获取self,这样我就可以访问它类型的__name__属性。

我可以让脚本编写者手动编辑一个新的字段来保存类型的名称,但为什么要这样呢?这些信息已经存在(就是__name__属性),所以为什么要重复呢?更重要的是,为什么要让脚本编写者处理这些实现细节呢?

3 个回答

0

在Python中,self就相当于C++中的this

你可以把这一行FooBar::func();想象成是变成了static_cast<FooBar*>(this)->func()

2

这是个老问题,但对于那些仍在寻找相对简单解决方案的人来说:

静态函数(无论是成员函数还是非成员函数)都会把一个 const boost::python::object& self 作为第一个参数传入。所以你可以这样做:

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)
     ;
}
2

这是可以实现的。具体的做法可以在下面的链接找到;那一页记录了一种方法(旧方法)来暴露纯虚函数。不过,这个例子也可以根据其他需求进行调整。
> http://wiki.python.org/moin/boost.python/OverridableVirtualFunctions#Pure_Virtual_Functions

撰写回答