Как вы передаете kwargs в обернутую функцию boost-python?

У меня есть функция python с этой подписью:

def post_message(self, message, *args, **kwargs):

Я хотел бы вызвать функцию из С++ и передать ей несколько kwargs. Вызов функции не проблема. Зная, как передать kwargs является. Вот нерабочий перефразированный образец:

std::string message("aMessage");
boost::python::list arguments;
arguments.append("1");

boost::python::dict options;
options["source"] = "cpp";

boost::python::object python_func = get_python_func_of_wrapped_object()
python_func(message, arguments, options)

Когда я использую этот код, в pdb я получаю (чего мне не хотелось бы):

messsage = aMessage
args = (['1'], {'source': 'cpp'})
kwargs = {}

Как вы передаете options в моем примере в словарь **kwargs?

Я видел один сообщение предлагая использовать синтаксис **options (как это круто!):

python_func(message, arguments, **options)

К сожалению, это приводит к

TypeError: No to_python (by-value) converter found for C++ type: class boost::python::detail::kwds_proxy

Спасибо за любую помощь, которую вы можете оказать.


person David    schedule 28.06.2011    source источник


Ответы (1)


После некоторого расследования выясняется, что оператор вызова объектной функции переопределен для двух аргументов типа args_proxy и kwds_proxy. Таким образом, вы должны использовать этот особый стиль вызова двух аргументов.

args_proxy и kwds_proxy генерируются * перегрузками. Это действительно приятно.

Кроме того, первый аргумент должен быть типа кортежа, чтобы интерпретатор Python правильно обрабатывал аргумент *args.

Полученный пример работает:

boost::python::list arguments;
arguments.append("aMessage");
arguments.append("1");

boost::python::dict options;
options["source"] = "cpp";

boost::python::object python_func = get_python_func_of_wrapped_object()
python_func(*boost::python::tuple(arguments), **options)

Надеюсь это поможет...

person David    schedule 29.06.2011
comment
Ничего себе, я не знал о перегрузках * и **, одной из тех крошечных деталей, которые делают boost::python замечательным. - person eudoxos; 05.07.2011
comment
Обратите внимание, что даже если используются только kwargs, в качестве первого аргумента необходим кортеж. Однако он может быть пустым: python_func(*boost::python::tuple(), **options). - person luator; 18.06.2018