创建带调用策略的属性 - boost::python
我有一些C++类,想要让它们在Python中使用。
class PlainOldData
{
...
};
class FancyClass
{
public:
const PlainOldData& GetMyPOD() {return myPOD;}
private:
PlainOldData myPOD;
};
因为我希望我的Python类看起来更像Python的风格,所以我想把myPOD作为一个属性来暴露出来。但是,当我尝试这样做的时候:
// expose with boost::python
BOOST_PYTHON_MODULE(mymod)
{
class_<PlainOldData>("PlainOldData", init<>());
// this fails
class_<FancyClass>("FancyClass", init<>())
.add_property("myPOD", &FancyClass::GetMyPOD);
}
我遇到了一个错误:error C2027: use of undefined type 'boost::python::detail::specify_a_return_value_policy_to_wrap_functions_returning<T>'
但是,如果我尝试指定一个调用策略,比如:
class_<FancyClass>("FancyClass", init<>())
.add_property("myPOD", &FancyClass::GetMyPOD, return_value_policy<copy_const_reference>());
我就会收到一个非常长的错误信息。
我想知道是否可以把这个函数作为属性暴露出来;我是不是做错了什么?
1 个回答
4
就像Python的 property()
可以接受Python的可调用对象一样,boost::python::class_::add_property()
这个函数也可以接受Python的可调用对象。这些对象可以通过CallPolicies 创建,比如通过boost::python::make_function()
返回的对象。
举个例子,原始代码中的属性可以这样暴露出来:
class_<FancyClass>("FancyClass", init<>())
.add_property("myPOD", make_function(&FancyClass::GetMyPOD,
return_value_policy<copy_const_reference>()));
下面是一个完整的简单示例:
#include <boost/python.hpp>
class egg {};
class spam
{
public:
const egg& get_egg() { return egg_; }
private:
egg egg_;
};
BOOST_PYTHON_MODULE(example)
{
namespace python = boost::python;
python::class_<egg>("Egg");
python::class_<spam>("Spam")
.add_property("egg", python::make_function(&spam::get_egg,
python::return_value_policy<python::copy_const_reference>()))
;
}
互动使用:
>>> import example
>>> spam = example.Spam()
>>> assert(spam.egg is not spam.egg) # unique identities as spam.egg
# returns a copy
>>> egg1 = spam.egg
>>> assert(egg1 is not spam.egg)
>>> egg2 = spam.egg
>>> assert(egg1 is not egg2)