8

我有一个 C++ 类,我正在使用 boost::python 将其构建到 python 模块中。我有一些函数要使用关键字参数。我已经设置了包装函数以传递给 raw_arguments 并且工作正常,但我想为函数参数构建一些错误检查。有没有标准的方法来做到这一点?

我的 C++ 函数原型看起来有点像这样:

double MyClass::myFunction(int a, int b, int c);

第三个参数是可选的,默认值为 0(到目前为止,我已经在 boost::python 中使用宏实现了这一点)。在python中,我希望能够实现以下行为:

MyClass.my_function(1) # Raises exception
MyClass.my_function(2, 3) # So that a = 2, b = 3 and c defaults to 0
MyClass.my_function(2, 3, 1) # As above, but now c = 1
MyClass.my_function(2, 3, 1, 3) # Raises exception
MyClass.my_function(3, 1, c = 2) # So a = 3, b = 1 and c = 2
MyClass.my_function(a = 2, b = 2, c = 3) # Speaks for itself
MyClass.my_function(b = 2, c = 1) # Raises exception

boost::python 或 raw_function 包装器中是否有可以促进这一点的东西,还是我需要自己编写代码来检查所有这些?如果我确实需要,我该如何提出例外?有这样做的标准方法吗?

4

1 回答 1

15

boost/python/args.hpp文件提供了一系列用于指定参数关键字的类。特别是,Boost.Python 提供了一个arg类型,它代表一个潜在的关键字参数。它重载了逗号运算符以允许对参数列表进行更自然的定义。

暴露myFunctionMyClassas my_function、 where abc是关键字参数,并且c具有默认值0可以写成如下:

BOOST_PYTHON_MODULE(example)
{
  namespace python = boost::python;
  python::class_<MyClass>("MyClass")
    .def("my_function", &MyClass::myFunction,
         (python::arg("a"), "b", python::arg("c")=0))
    ;
}

这是一个完整的例子:

#include <boost/python.hpp>

class MyClass
{
public:
  double myFunction(int a, int b, int c)
  {
    return a + b + c;
  }
};

BOOST_PYTHON_MODULE(example)
{
  namespace python = boost::python;
  python::class_<MyClass>("MyClass")
    .def("my_function", &MyClass::myFunction,
         (python::arg("a"), "b", python::arg("c")=0))
    ;
}

互动使用:

>>> import example
>>> my_class = example.MyClass()
>>> my_class.my_function(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
Boost.Python.ArgumentError: Python argument types in
    MyClass.my_function(MyClass, int)
did not match C++ signature:
    my_function(MyClass {lvalue}, int a, int b, int c=0)
>>> assert(5 == my_class.my_function(2, 3))
>>> assert(6 == my_class.my_function(2, 3, 1))
>>> my_class.my_function(2, 3, 1, 3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
Boost.Python.ArgumentError: Python argument types in
    MyClass.my_function(MyClass, int, int, int, int)
did not match C++ signature:
    my_function(MyClass {lvalue}, int a, int b, int c=0)
>>> assert(6 == my_class.my_function(3, 1, c=2))
>>> assert(7 == my_class.my_function(a=2, b=2, c=3))
>>> my_class.my_function(b=2, c=1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
Boost.Python.ArgumentError: Python argument types in
    MyClass.my_function(MyClass)
did not match C++ signature:
    my_function(MyClass {lvalue}, int a, int b, int c=0)
于 2013-05-21T13:44:29.500 回答