3

我有一个 C++ 函数,它需要一个vector< pair< pair<string,string>, string > >我希望从 python 调用的函数。

我写了一个包装如下:

bool create_cache_wrapper(boost::python::tuple tup_)
{
  vector< pair< pair<string,string>, string > > rbv;
  for(int i=0;i<py::len(tup_);++i)
  {
    std::string start,end,bucket;
    bucket = py::extract<std::string>(tup_[i][1]);
    start = py::extract<std::string>(tup_[i][0][0]);
    end = py::extract<std::string>(tup_[i][0][1]);
    rbv.push_back(make_pair(make_pair(start,end),bucket));
  }
  return create_cache(rbv);
}

我已经用python注册了这个函数,如下所示:

BOOST_PYTHON_MODULE(my_lib)
{
  using namespace boost::python;
  def("create_cache", create_cache_wrapper);
}

这很好用,但问题是,它只接受一个元组而不接受一个列表。如何编写包装器以使其适用于 python 中的任何序列容器?有没有更好的方法来做到这一点而无需编写包装器?我希望 python api 像

create_cache( ( (('',''),'b1'), ) )
create_cache( [ (('',''),'b1')  ] )
4

2 回答 2

2

这可以通过让包装器取一个对象来实现:

bool create_cache_wrapper(boost::python::object tup_)
{
    // ...
}

py::len()并且索引运算符应该在对象上工作,如果所讨论的类型不支持len()或索引,它们应该引发 Python 错误。这应该允许调用者提供任何可索引的类型,甚至是用户定义的类型!

于 2013-08-02T22:07:50.627 回答
1

我通常使用boost python 迭代器包装器来实现您所描述的 - 它适用于任何类型的可迭代。我在下面修改了您的代码,以便您对如何自己做一个想法:

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

using namespace boost::python;

bool create_cache_wrapper(object iterable)
{
  stl_input_iterator<object> end;
  for(std_input_iterator<object> i(iterable); i!=end; ++i)
  {
    std::string start,end,bucket;
    bucket = py::extract<std::string>((*i)[1]);
    start = py::extract<std::string>((*i)[0][0]);
    end = py::extract<std::string>((*i)[0][1]);
    rbv.push_back(make_pair(make_pair(start,end),bucket));
  }
  return create_cache(rbv);
}

您可以一直使用stl_input_iterator,即使对于第一个可迭代对象中的对。

于 2013-08-04T06:51:22.050 回答