在嵌入式python场景中,我们使用PyArg_ParseTupleAndKeywords
从Python接收数据(版本> = 3 .x)并在C ++应用程序中使用它。
目前我们有类似的设置:
PyObject* whatever(PyObject *self, PyObject *args, PyObject *keywds) {
....
static char* kwlist[] = { "foo", "bar", NULL };
...
if(!PyArg_ParseTupleAndKeywords(args, keywds, ..., kwlist, ...))
{
...bail out
但是,如果我们传递的参数多于预期的两个参数(例如发出像whatever(foo="a", bar="b", baz="c")
这样的python调用),整个事情就会崩溃(不是真的,它会返回一个错误,但这超出了这里的范围)。
我们希望避免这种情况;如果我们只能解析 kwlist
中的参数并忽略其他参数,那就太好了。最好的方法是什么?
我们考虑的一个解决方案是将kwlist
转换为dict
,然后使用PyDict_Merge
等操作它。
答案 0 :(得分:2)
最后我们解决了它,如下所示:
(我回答了我自己的问题,因为没有人回答,我认为这对其他人来说可能是有价值的。)
PyObject* whatever(PyObject *self, PyObject *args, PyObject *incoming_keywds)
{
static char* kwlist[] = { "foo", "bar", NULL };
PyObject* keywds = PyDict_New();
/**
* The following routine returns a subset of the incoming dictionary 'incoming_keywds'
* containing only the keys allowed in the list 'kwlist'
*/
for ( int i = 0 ; kwlist[i] != NULL ; i++ )
{
char* key = kwlist[i];
PyObject *single_key = Py_BuildValue("s", key);
if ( PyDict_Contains(incoming_keywds, single_key) )
{
// not checking for NULL as GetItem return value since
// we already checked above if the dict contains key 'single_key'
if ( PyDict_SetItem(keywds, single_key, PyDict_GetItem(incoming_keywds, single_key)) < 0 )
{
/* error */
}
}
Py_DECREF(single_key);
}
/** end */