我正在调用一个函数,它接受一个位置参数列表,后跟关键字参数。我想分别处理args和kwargs。不幸的是,与位置参数的PyArg_ParseTuple不同,关键字参数没有等效的PyArg_ParseKeywords。我试图通过传递Py_None(也是NULL)来代替args来阻止解析位置参数:
static PyObject* test_func(PyObject* self, PyObject* args, PyObject *kwargs)
{
static const char *kwList[] = {"kw1", "kw2", NULL};
const char* kw1_val = NULL;
PyObject* kw2_val = NULL;
if (! PyArg_ParseTupleAndKeywords(Py_None,
kwargs,
"zO",
const_cast<char**>(kwList),
&kw1_val,
&kw2_val))
{
return NULL;
}
}
有Py_None(或NULL)导致:
Python/getargs.c:1390: bad argument to internal function
如果我用args替换Py_None,我会收到以下错误:
TypeError: function takes at most 2 arguments (4 given)
上面发生TypeError,因为它解包了2个位置args和2个传递给test_func的关键字args,而只有两个变量kw1_val和kw2_val在解析方法中接收这4个值。
有没有办法处理上述情况?请注意,位置参数可以包含任意数量的值。
答案 0 :(得分:2)
尝试传递空元组而不是Py_None
:
static PyObject* test_func(PyObject* self, PyObject* args, PyObject *kwargs)
{
static const char *kwList[] = {"kw1", "kw2", NULL};
const char* kw1_val = NULL;
PyObject* kw2_val = NULL;
PyObject *retvalue = NULL;
PyObject *empty = PyTuple_New(0);
if (empty == NULL){
goto out;
}
if (! PyArg_ParseTupleAndKeywords(empty,
kwargs,
"zO",
const_cast<char**>(kwList),
&kw1_val,
&kw2_val))
{
goto out;
}
// other code here
out:
Py_XDECREF(empty);
return retvalue;
}
答案 1 :(得分:0)
我认为您在这里遇到了经典的X-Y问题。不用担心,我有相同的人。
这里的Y是PyArg_ParseTupleAndKeywords
,而实际上X只是“在Python C API中仅解析kwargs
”。
kwargs
只是一个Python dict()
,因此,如果我们真的不在乎位置参数,则可以使用现有的C API函数来处理dict()
,PyDict_*
family of functions。
因此,如果我们有PyCFunction
个原型:
PyObject* Amit(PyObject *self, PyObject *args, PyObject *keywds);
我们知道keywds
在Python 2和Python 3中都是PyDict
。因此我们可以例如这个:
PyObject* layerp = NULL;
if (keywds != NULL) layerp = PyDict_GetItemString(keywds, "layer");
PyDict_GetItemString
将返回NULL
而不会设置错误,因此我们只需检查layerp
中的NULL
即可知道是否有可选的关键字参数。>
答案 2 :(得分:-1)
c++ 按键排序
p::list l;
l.sort(*tuple(), **dict(make_tuple(make_tuple("key", *[](object const& x){ return x["y"];}))));