使用PyArg_ParseTupleAndKeywords时排除不相关的参数

时间:2011-11-02 13:28:40

标签: python-3.x

在嵌入式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等操作它。

1 个答案:

答案 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 */