如何使用Boost Python函数在C ++中定义,该函数在功能上等同于Python函数
def test():
return list
答案 0 :(得分:2)
虽然Boost.Python TypeWrappers提供了一种方便的方法来实例化某些内置Python类型的对象,但Boost.Python并不直接支持第一类对象本身。但是,可以通过Python / C API中相应的PyTypeObject
对象通过Boost.Python返回第一类对象。
在这种特殊情况下,Python {C} API中的Python list
类型为PyList_Type
。 Python代码:
def test():
return list
等同于以下C ++ Boost.Python代码:
boost::python::object test()
{
namespace python = boost::python;
python::handle<PyTypeObject> handle(python::borrowed(&PyList_Type));
return python::object(handle);
}
混合Python / C API和更高级别的Boost.Python代码时,必须使用boost::python::handle
从PyObject
对象或带有<的对象构造boost::python::object
i>派生(布局兼容)类型,例如PyTypeObject
。 handle
本质上是一个智能指针,负责处理Python引用计数。 handle
的析构函数将始终递减关联的Python对象的引用计数。因此,在构造handle
时必须小心,因为必须知道handle
是否需要增加引用计数或者它是否已经递增。如果引用计数尚未增加(例如在上面的代码中),则必须将返回类型boost::python::borrowed()
传递给handle
的构造函数。有关详细信息,请参阅此link。
这是一个完整的例子:
#include <boost/python.hpp>
boost::python::object test()
{
namespace python = boost::python;
python::handle<PyTypeObject> handle(python::borrowed(&PyList_Type));
return python::object(handle);
}
BOOST_PYTHON_MODULE(example)
{
namespace python = boost::python;
python::def("test", &test);
}
交互式使用:
>>> import example
>>> assert(example.test() is list)
>>> t = example.test()
>>> assert(t((1, 2, 3)) == [1, 2, 3])
>>> assert(t((1, 2, 3)) != (1, 2, 3))
>>> del t
>>> from sys import getrefcount # test for proper reference counting
>>> n = getrefcount(list)
>>> t = example.test()
>>> assert(n + 1 == getrefcount(list))
>>> del t
>>> assert(n == getrefcount(list))