ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

C列表到Python列表

2019-06-29 08:46:46  阅读:208  来源: 互联网

标签:python c-2 type-conversion boost boost-python


我正在为现有的C库编写一个包装器,它利用了列表,其中T是一个自定义结构.我被建议使用vector而不是list,但我试图避免修改库.

为了更好地理解场景,我做了一个简单的应用程序,使用列表作为注册to-python转换的代理(可以只读).

我当前的实现编译很好,python导入很好,可以创建对象,但是当我调用数据成员时,它会出错.

python shell输出:

In [1]: import my_list

In [2]: x = my_list.Bob()

In [3]: x.foos
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-3-2f015d13a87d> in <module>()
----> 1 x.foos

TypeError: No Python class registered for C++ class std::list<int, std::allocator<int> >

C档案:

#include <list>
#include <boost/python.hpp>

#include <boost/foreach.hpp>
#ifndef FOREACH
    #define FOREACH BOOST_FOREACH
#endif

using namespace std;
using namespace boost::python;

template<typename T>
struct list_to_list
{
    static PyObject* convert(const std::list<T>& src)
    {
        boost::python::list result;
        FOREACH (const T& val, src)
        {
            result.append(val);
        }

        return incref(result.ptr());
    }
};

struct Bob
{
    std::list<int> foos;
};

BOOST_PYTHON_MODULE(my_list)
{
    using namespace boost::python;

    to_python_converter<std::list<int>, list_to_list<int> >();

    class_<Bob>("Bob")
        .def_readonly("foos", &Bob::foos)
    ;
}

我错过了什么吗?

解决方法:

FAQ中所述,通过def_readonly(),def_readwrite()和add_property()以及默认策略公开的属性将不使用自定义转换器.要解决此问题,请使用add_property()替换def_readonly()和def_readwrite(),提供类型为boost::python::return_by_valueboost::python::return_value_policy.

在原始代码中,它将是:

BOOST_PYTHON_MODULE(my_list)
{
  using namespace boost::python;

  to_python_converter<std::list<int>, list_to_list<int> >();

  class_<Bob>("Bob")
    .add_property("foos", make_getter(&Bob_foos,
        return_value_policy<return_by_value>())) 
    ;
}

这是一个完整的例子:

#include <list>
#include <boost/assign/list_of.hpp>
#include <boost/foreach.hpp>
#include <boost/python.hpp>

namespace python = boost::python;

/// @brief Type to convert from an iterable to a Python list.
template <typename T>
struct list_to_list
{
  static PyObject* convert(const std::list<T>& container)
  {
    python::list result;
    BOOST_FOREACH(const T& value, container)
      result.append(value);
    return python::incref(result.ptr());
  }
};

/// @brief mockup type.
struct Spam
{
  Spam()
  {
    foos = boost::assign::list_of(1)(2)(3)(5);
  }

  std::list<int> foos;
};

BOOST_PYTHON_MODULE(example)
{
  // Enable std::list<int> to Python list conversion.
  python::to_python_converter<std::list<int>, list_to_list<int> >();

  python::class_<Spam>("Spam")
    .add_property("foo", python::make_getter(&Spam::foos,
          python::return_value_policy<python::return_by_value>()))
    ;
}

由此产生的用法:

>>> import example
>>> spam = example.Spam()
>>> spam.foo
[1, 2, 3, 5]

标签:python,c-2,type-conversion,boost,boost-python
来源: https://codeday.me/bug/20190629/1324784.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有