bp :: extract将bp :: object转换为特定类型.问题是怎么做副歌?
我们假设我有一个PointContainer和Point类.我需要一个具有这种签名的功能
bp::object get_point(const PointContainer &, const bp::object & input);
Run Code Online (Sandbox Code Playgroud)
它应检查输入参数是否为整数.在这种情况下,它返回PointContainer中具有相应索引的Point实例的引用.如果它不是整数,那么函数检查输入是否是切片对象(例如mylist [1:10:2]).在这种情况下,它返回PointContainer的副本.
问题是如何将Point,PointContainer实例转换为bp :: objects?
有关上述课程的一些细节
class_<Point<int>>("Point")
.def("__getitem__", get_point_item)
.def("__setitem__", set_point_item)
.def("__len__", get_point_size)
.def("__str__", print_point)
.def("__eq__", &Point<int>::operator ==)
.def("__ne__", &Point<int>::operator !=)
.def("set_x", &Point<int>::set_x)
.def("get_x", &Point<int>::get_x)
.def("set_y", &Point<int>::set_y)
.def("get_y", &Point<int>::get_y)
;
typedef std::vector<Point<int>> PointContainer;
typedef boost::shared_ptr<PointContainer> PointContainerPtr;
class_<PointContainer, PointContainerPtr>("PointContainer")
.def("__iter__", iterator<PointContainer>())
.def("__getitem__", get_point)
.def("__setitem__", set_point)
.def("__len__", &PointContainer::size)
.def("append", push_point)
.def("reserve", &PointContainer::reserve)
.def("clear", &PointContainer::clear)
;
Run Code Online (Sandbox Code Playgroud)
对于其类型已公开boost::python::class_的C++对象,可以使用以下构造函数构造具有C++对象实例的Python对象:
Run Code Online (Sandbox Code Playgroud)template <class T> explicit object(T const& x);效果:转换
x为python并管理对它的引用.抛出: 如果不可能进行这样的转换,则
error_already_set设置PythonTypeError异常.
当一个类型通过via公开时boost::python::class_,Boost.Python将注册到C++类型的-python和from-python转换器.当使用模板化的构造函数时object(),它将检查内部注册表中的to-python转换器并在找到时使用它.生成的Python对象将拥有并拥有自己的C++对象实例.
这是一个完整的最小示例,演示了如何boost::python::object从C++对象构造:
#include <boost/python.hpp>
// Mockup types.
class spam {};
class egg {};
// Factory function that returns boost::python::objects.
boost::python::object make_object(std::string name)
{
namespace python = boost::python;
if (name == "spam") return python::object(spam{});
else if (name == "egg") return python::object(egg{});
else return python::object();
}
BOOST_PYTHON_MODULE(example)
{
namespace python = boost::python;
// Expose models.
python::class_<spam>("Spam", python::init<>());
python::class_<egg>("Egg", python::init<>());
// Expose factory function.
python::def("make_object", &make_object);
}
Run Code Online (Sandbox Code Playgroud)
互动用法:
>>> import example
>>> assert(type(example.make_object("spam")) is example.Spam)
>>> assert(type(example.make_object("egg")) is example.Egg)
>>> assert(example.make_object("bogus") is None)
Run Code Online (Sandbox Code Playgroud)
如果需要不同的返回值语义,例如boost::python::object应该引用现有的C++对象而不是副本,则需要在包装C++函数时提供调用策略.