的boost :: Python-可以自动从字典转换 - >性病::地图吗? [英] Boost::Python- possible to automatically convert from dict --> std::map?
问题描述
我有一个C ++类,与可拿一个小到大量参数的成员函数。让我们命名这些参数,A-F。所有的参数都有默认值。由于我工作的Python项目的一部分,我想这个类暴露在蟒蛇。目前,成员函数看起来是这样的:
I've got a C++ class, with a member function that can take a small-to-large number of parameters. Lets name those parameters, a-f. All parameters have default values. As a part of the python project I am working on, I want to expose this class to python. Currently, the member function looks something like this:
class myClass {
public:
// Constructors - set a-f to default values.
void SetParameters(std::map<std::string, double> &);
private:
double a, b, c, d, e, f;
}
void myClass::SetParameters(std::map<std::string, double> const& params) {
// Code to iterate over the map, and set any found key/value pairs to their
// corresponding variable. i.e.- "a" --> 2.0, would set myClass::a to 2.0
}
在理想情况下,在Python,我想做到这一点使用的字典:
Ideally, in Python, I would like to accomplish this using a dict:
>>> A = myModule.myClass();
>>> A.SetParameters({'a': 2.2, 'd': 4.3, b: '9.3'})
在这种方式中,用户可以按任何顺序输入值,然后输入任意数量的人将超过缠身。这是如何能够在升压::蟒蛇来完成有什么想法?在我看来,我可以通过改变地图输入到一个boost :: Python对象,并使用提取功能做到这一点。然而,这需要我改变我的库接口(我preFER保持的std ::地图界面,并具备为Python版本一些中介/自动转换技术)。思考?
In this way, the user could enter the values in any order, and enter any number of them to be over-ridden. Any thoughts on how this could be accomplished in boost::python? It seems to me that I can do this via changing the map input to a boost::python object, and using the extract functions. However, this would require me to change the interface of my library (I'd prefer to keep the std::map interface, and have some intermediary/auto conversion technique for the python version). Thoughts?
推荐答案
我觉得有几个是更容易完成比写你自己的方式转换。您可以使用boost :: python的map_indexing_suite做转换为你,或者你可以在Python中使用关键字参数。我个人preFER关键字参数,因为这是更Python化的方式来做到这一点。
I think there's a couple of ways that are easier to accomplish than writing your own converter. You can use boost::python's map_indexing_suite to do the conversion for you, or you can use keyword arguments in python. I personally prefer keyword arguments, as this is the more "Pythonic" way to do this.
这是你的类(我添加了地图的typedef):
So this is your class (I added a typedef for the map):
typedef std::map<std::string, double> MyMap;
class myClass {
public:
// Constructors - set a-f to default values.
void SetParameters(MyMap &);
private:
double a, b, c, d, e, f;
};
例使用map_indexing_suite:
Example using map_indexing_suite:
#include <boost/python/suite/indexing/map_indexing_suite.hpp>
using boost::python;
BOOST_PYTHON_MODULE(mymodule)
{
class_<std::map<std::string, double> >("MyMap")
.def(map_indexing_suite<std::map<std::wstring, double> >() );
class_<myClass>("myClass")
.def("SetParameters", &myClass::SetParameters);
}
使用关键字参数为例。这就需要使用raw_function包装:
Example using keyword arguments. This requires using a raw_function wrapper:
using namespace boost::python;
object SetParameters(tuple args, dict kwargs)
{
myClass& self = extract<myClass&>(args[0]);
list keys = kwargs.keys();
MyMap outMap;
for(int i = 0; i < len(keys); ++i) {
object curArg = kwargs[keys[i]];
if(curArg) {
outMap[extract<std::string>(keys[i])] = extract<double>(kwargs[keys[i]]);
}
}
self.SetParameters(outMap);
return object();
}
BOOST_PYTHON_MODULE(mymodule)
{
class_<myClass>("myClass")
.def("SetParameters", raw_function(&SetParameters, 1));
}
这允许你写这样的东西在Python:
this allows you to write stuff like this in Python:
A.SetParameters(a = 2.2, d = 4.3, b = 9.3)
这篇关于的boost :: Python-可以自动从字典转换 - &GT;性病::地图吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!