Извлечение аргументов из kwargs в boost :: python

У меня есть класс C ++, который я встраиваю в модуль python, используя boost :: 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, которая может облегчить это, или мне нужно написать код, чтобы проверить все это самому? Если мне нужно, как я могу поднять исключения? Есть ли стандартный способ сделать это?

6

Решение

boost/python/args.hpp Файл предоставляет семейство классов для указания ключевых слов аргумента. В частности, Boost.Python предоставляет arg тип, представляющий потенциальный аргумент ключевого слова. Он перегружает оператор запятой, чтобы обеспечить более естественное определение списка аргументов.

Разоблачение myFunction на MyClass как my_function, где a, b, а также c являются ключевыми аргументами, и 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)
13

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]