C++ List 到 Python List 的转换

这篇具有很好参考价值的文章主要介绍了C++ List 到 Python List 的转换。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

当我们编写 C++ 库的封装器通常涉及使用一种跨语言的接口技术,比如使用C接口或者使用特定的跨语言库,比如SWIG(Simplified Wrapper and Interface Generator)或者Pybind11。这里我将简要介绍如何使用Pybind11来封装一个C++库,以便在Python中使用。

C++ List 到 Python List 的转换,c++,list,python,pygame,windows,开发语言

1、问题背景

在编写 C++ 库的封装器时,需要将 C++ 中的 list 容器转换为 Python 中的 list。由于 C++ 库不能被修改,因此希望避免使用 vector 来替代 list。

为了更好地理解这种情况,使用 list 作为代理来注册从 C++ 到 Python 的转换(只读)。当前的实现可以编译,Python 可以正常导入,并且可以创建对象,但是在调用数据成员时会出错。

Python 控制台输出:

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)
    ;
}

2、解决方案

如常见问题解答中所述,通过 def_readonly()def_readwrite()add_property() 暴露的属性,使用默认策略不会使用自定义转换器。要解决此问题,请用 add_property() 替换 def_readonly()def_readwrite(),提供一个 boost::python::return_value_policy,其类型为 boost::python::return_by_value

在原始代码中,它应该是:

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]

上面这个就是一个简单的例子,展示了如何使用Pybind11来封装一个C++库。具体的细节可能会因为我们的C++库的复杂性而有所不同,但这应该可以帮助你入门。如果有更多的问题可以留言讨论。文章来源地址https://www.toymoban.com/news/detail-854820.html

到了这里,关于C++ List 到 Python List 的转换的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 0829|C++day7 auto、lambda、C++数据类型转换、C++标准模板库(STL)、list、文件操作

    0829|C++day7 auto、lambda、C++数据类型转换、C++标准模板库(STL)、list、文件操作

        封装一个学生的类,定义一个学生这样类的vector容器, 里面存放学生对象(至少3个) 再把该容器中的对象,保存到文件中。 再把这些学生从文件中读取出来,放入另一个容器中并且遍历输出该容器里的学生。

    2024年02月10日
    浏览(12)
  • c++(8.29)auto关键字,lambda表达式,数据类型转换,标准模板库,list,文件操作+Xmind

    c++(8.29)auto关键字,lambda表达式,数据类型转换,标准模板库,list,文件操作+Xmind

    封装一个学生的类,定义一个学生这样类的vector容器, 里面存放学生对象(至少3个) 再把该容器中的对象,保存到文件中。 再把这些学生从文件中读取出来,放入另一个容器中并且遍历输出该容器里的学生。  1.模板类 2.异常(异常情况为取钱时取的钱小于0或者大于余额)

    2024年02月11日
    浏览(15)
  • python速学list及list.append等方法

    列表(list)和元组(tuple)比较相似,它们都按顺序保存元素,每个元素都有自己的索引,因此列表和元组都可通过索引访问元素。二者的区别在于元组是不可修改的,但列表是可修改的。 解释:  Append object to the end of the list. 格式: def append(self, *args, **kwargs),list.append(追

    2024年02月05日
    浏览(11)
  • list.stream.filter,List<List>转换为List

    可以使用流(Stream)的`flatMap`操作 在这个示例中,我们首先创建了一个嵌套的 List 对象 nestedList ,其中包含了多个 List 。然后,我们使用流的 flatMap 操作将嵌套的 List 展开为一个平铺的 List ,最后使用 collect 方法将结果收集到一个新的 List 对象 flatList 中。最后,我们打印出 f

    2024年02月13日
    浏览(12)
  • list转换为arrayList——arrayList转换为list

    1、区别:list是一个接口;array List是一个类 2、两者都是集合. 为什么要转换呢? 因为ArrayList 类型不安全,效率较低。 List一点安全,效率比ArrayList要高。 list转array list array list转list

    2024年02月12日
    浏览(11)
  • Python 列表(List)

    目录 访问列表中的值 实例(Python 2.0+) 更新列表 实例(Python 2.0+) 删除列表元素

    2024年02月17日
    浏览(9)
  • 【Python】列表list

    目录 2.1 列表list 1)切片、索引 2)append、extend、insert 3)index、count 4)len、sum、max、min 5)sort、reverse 6)加法(合并)和乘法(重复) 7)列表解析式 索引 列表是一种有序的数据结构,可以存储任意类型的元素。列表中的元素可以通过索引进行访问,索引从 0 开始,表示列表

    2024年02月08日
    浏览(31)
  • python的列表list

    一.添加  二.insert添加 三.extend添加  四.删除remove 五.pop()删除 六.pop(索引)  七.del 删除 八.clear清除内容  

    2024年02月05日
    浏览(10)
  • Java:List转换List

    我们经常会遇到泛型转换泛型的时候,今天我们就介绍下使用java1.8和普通转换,其中测试数据自行添加 一、 ListObject  转  ListString 二、 ListObject  转  ListObject   三、 ListObject1  转  ListObject2 四、 ListObject1  转  ListObject2(普通转换)

    2024年01月16日
    浏览(10)
  • python:给List添加元素

    List 是 Python 中常用的数据类型,它一个有序集合,即其中的元素始终保持着初始时的定义的顺序(除非你对它们进行排序或其他修改操作)。 在Python中,向List添加元素,方法有如下4种方法(append(),extend(),insert(), +加号) 此元素如果是一个list,那么这个list将作为一个整体进

    2024年02月08日
    浏览(7)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包