boost.python 对类似构造函数感到困惑
我有一个类,长得像这样:
class Foo{
Foo();
Foo(int i);
Foo(bool b);
Foo(double d);
};
然后我像往常一样把这个类暴露给Python使用。
class_<Foo>("Foo")
.def(init<int>())
.def(init<bool>())
.def(init<double>());
但是当我在Python中使用这个类时,Python代码总是把构造函数的参数转换成双精度浮点数(也就是类定义中最后一个参数的类型)。有没有办法明确告诉boost.python怎么根据类型来处理这些参数呢?
1 个回答
13
好吧,你可以改变构造函数的定义顺序,最后一个定义的优先级会更高。这里是我的结果:
class_<Foo>("Foo")
.def(init<bool>())
.def(init<double>())
.def(init<int>());
Foo() # calls Foo()
Foo(True) # calls Foo(int)
Foo(1) # calls Foo(int)
Foo(4.2) # calls Foo(double)
如你所见,这并不是一个完美的解决方案。所以,如果你真的需要让重载的构造函数正常工作,我建议你自己写一个工厂函数。
using namespace boost::python;
static boost::shared_ptr<Foo>
makeFoo(const object& data)
{
boost::shared_ptr<Foo> obj;
if (PyBool_Check(data.ptr())) {
bool val = extract<bool>(data);
obj.reset(new Foo(val));
}
else if (PyFloat_Check(data.ptr())) {
double val = extract<double>(data);
obj.reset(new Foo(val));
}
else {
int val = extract<int>(data);
obj.reset(new Foo(val));
}
return obj;
}
class_<Foo>("Foo")
.def("__init__", make_constructor(makeFoo));
然后使用 makeFoo:
Foo() # calls Foo()
Foo(True) # calls Foo(bool)
Foo(1) # calls Foo(int)
Foo(4.2) # calls Foo(double)
顺便提一下,python.org上的文档可能会对你有点帮助。