У меня есть класс 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, которая может облегчить это, или мне нужно написать код, чтобы проверить все это самому? Если мне нужно, как я могу поднять исключения? Есть ли стандартный способ сделать это?
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)
Других решений пока нет …