Boost::Python- 可以从 dict 自动转换 -->标准::地图?
我有一个 C++ 类,其中有一个可以接受从小到大数量的参数的成员函数。让我们将这些参数命名为 af。所有参数都有默认值。作为我正在开发的 python 项目的一部分,我想将此类公开给 python。目前,成员函数看起来像这样:
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中,我想使用字典来完成此操作:
>>> A = myModule.myClass();
>>> A.SetParameters({'a': 2.2, 'd': 4.3, b: '9.3'})
这样,用户可以按任何顺序输入值,并输入任意数量的值来覆盖。关于如何在 boost::python 中实现这一点有什么想法吗?在我看来,我可以通过将映射输入更改为 boost::python 对象并使用 extract 函数来做到这一点。但是,这需要我更改库的接口(我更愿意保留 std::map 接口,并为 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
}
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'})
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我认为有几种方法比编写自己的转换器更容易实现。您可以使用 boost::python 的 map_indexing_suite 来为您进行转换,也可以使用 python 中的关键字参数。我个人更喜欢关键字参数,因为这是更“Pythonic”的方式来做到这一点。
所以这是你的类(我为地图添加了 typedef):
使用 map_indexing_suite 的示例:
使用关键字参数的示例。这需要使用 raw_function 包装器:
这允许您在 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.
So this is your class (I added a typedef for the map):
Example using map_indexing_suite:
Example using keyword arguments. This requires using a raw_function wrapper:
this allows you to write stuff like this in Python:
这篇博文有一个漂亮的清楚地描述了如何编写这些转换器。基本模式是定义一个具有以下形式的类:
其中构造函数负责将此转换器添加到 Boost.Python 的注册表:
函数
convertible
告诉 Boost 此转换器是否可以转换指定的 Python对象:construct
函数实际上创建了一个转换类型的对象:然后在你的BOOST_PYTHON_MODULE内部,包括行
This blog post has a pretty clear description of how to write these converters. The basic pattern is to define a class that has the form:
Where the constructor is responsible for adding this converter to Boost.Python's registry:
The function
convertible
tells Boost whether or not this converter can convert the specified Python object:The
construct
function actually creates an object of the conversion type:and then in your inside your BOOST_PYTHON_MODULE, include the line
我只是用 boost::python 弄湿了我的脚趾,所以无法完全回答你的问题。但我看到的第一个障碍是保证 py 字典的键都是字符串。 Python 字典也可以在元组上键入(我假设有更多类型)。
I'm just getting my toes wet with boost::python so can't completely answer your question. But the first roadblock I see is guaranteeing that the py dict's keys are all strings. Python dicts can also be keyed on tuples (and I assume more types).