12

您可以使用 getter 和 setter 向类添加属性(在简单的情况下):

class<X>("X")
    .add_property("foo", &X::get_foo, &X::set_foo);

那么你可以像这样从 python 中使用它:

>>> x = mymodule.X()
>>> x.foo = 'aaa'
>>> x.foo
'aaa'

但是如何将属性添加到模块本身(不是类)?

scope().attr("globalAttr") = ??? something ???

def("globalAttr", ??? something ???);

我可以使用上述两种方式添加我的类的全局函数和对象,但似乎无法像在类中那样添加属性。

4

2 回答 2

3

__getattr__并且__setattr__不会在模块上调用,因此您无法在没有 hack 的普通 Python 中执行此操作(例如在模块字典中存储类)。鉴于此,在 Boost Python 中也不太可能有一种优雅的方式来做到这一点。

于 2010-04-29T06:08:47.947 回答
3

Python Wiki 上的boost.python/HowTo有一个将 C++ 对象公开为内部模块属性的示例BOOST_PYTHON_MODULE

namespace bp = boost::python;
BOOST_PYTHON_MODULE(example)
{
    bp::scope().attr("my_attr") = bp::object(bp::ptr(&my_cpp_object));
}

BOOST_PYTHON_MODULE使用之外设置属性

bp::import("example").attr("my_attr") = bp::object(bp::ptr(&my_cpp_object));

现在你可以在 python 中做类似的事情

from example import my_attr

当然,您需要my_cpp_object提前注册类(例如,您可以在同一个BOOST_PYTHON_MODULE调用中执行此操作)并确保 C++ 对象的生命周期超过 python 模块的生命周期。您可以使用 anybp::object而不是包装 C++ 之一。

请注意,它会BOOST_PYTHON_MODULE吞下异常,因此如果您犯了错误,您不会收到任何错误指示,并且BOOST_PYTHON_MODULE-generated 函数将立即返回。为了简化这种情况的调试,您可以在内部捕获异常BOOST_PYTHON_MODULE或临时添加一些日志记录语句作为最后一行BOOST_PYTHON_MODULE以查看是否已到达:

BOOST_PYTHON_MODULE(example)
{
    bp::scope().attr("my_attr2") = new int(1); // this will compile
    std::cout << "init finished\n"; // OOPS, this line will not be reached
}
于 2013-07-01T00:03:31.927 回答