如何从C ++返回Python类型的实例

时间:2014-06-09 17:37:44

标签: python c++ boost-python

如何使用Boost Python函数在C ++中定义,该函数在功能上等同于Python函数

def test():
    return list

1 个答案:

答案 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::handlePyObject对象或带有<的对象构造boost::python::object i>派生(布局兼容)类型,例如PyTypeObjecthandle本质上是一个智能指针,负责处理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))