Python C扩展中的True * args和** kwargs
我正在开发Python 3 C扩展。Python C扩展中的True * args和** kwargs
我可以得到等价的或任意的位置或关键字参数吗?
例如,在Python,我可以这样写:
def fun(name, parent, *args, **kwargs):
# do something with name and parent
# do something with args and kwargs
pass
但我不能找到一个简单的等同于C的同时,我们可以完美地写函数与PyObject* args
和PyObject* kwargs
,我不能轻易“解析出”名字和父母从它来的任何(args/kwargs)。
采取:
static PyObject* myFunction(PyObject* self, PyObject* args, PyObject* kwargs) {
char* kwds[] = {"parent", "name", NULL};
PyObject* name = NULL;
PyObject* parent = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO", kwds, &parent, &name)) {
goto errorParseTupleAndKeywords;
}
/* Do something with name and parent */
/* parent and name maybe have appeared either in args or kwargs */
/* But I don't have any extra positional (*args) or keyword (**kwargs) here */
}
A “手册” 的方法,我能想到看起来大致是:
static PyObject* myFunction(PyObject* self, PyObject* args, PyObject* kwargs) {
PyObject* name = NULL;
PyObject* parent = NULL;
int inKwargs = 0;
// Pretend to do something with parent
if (PyDict_GetItemString(kwargs, "parent")) {
inKwargs++;
PyDict_DelItemString(kwargs, "parent");
}
// Pretend to do something with name
if (PyDict_GetItemString(kwargs, "name")) {
inKwargs++;
PyDict_DelItemString(kwargs, "name");
}
// Not sure if -1 works here
PyObject* newArgs = PyTuple_GetSlice(args, inKwargs, -1); // this is *args
// the remaining kwargs can be used as **kwargs
}
在C API,PyObject* args
真的是一个Python元组和PyObject* kwargs
真的是一个Python字典。至少,这是什么PyArg_ParseTupleAndKeywords
internally要求:
int PyArg_ParseTupleAndKeywords(PyObject *args, PyObject *keywords, const char *format, char **kwlist, ...)
{
// …
if ((args == NULL || !PyTuple_Check(args)) ||
(keywords != NULL && !PyDict_Check(keywords)) ||
format == NULL ||
kwlist == NULL)
{
PyErr_BadInternalCall();
return 0;
}
// …
}
实际执行中vgetargskeywords
该功能也再次发出这个,所以你应该罚款与由画手工提取更换您的通话PyArg_ParseTupleAndKeywords
。
这意味着您可以同时使用tuple和dict API,也可以使用iterator protocol遍历这些对象中的项目。
是的,我知道'PyObject * args'是一个元组,而'PyObject * kwargs'是一个字典;在问题的第三个代码块(“手动”方法)中,我使用了元组和字典API。不足之处在于代码需要极大的空间并且不太易读,也就是说,你不能立即从这15行中得知它们的意图是像'def fun(name,parent,* args, ** kwargs)'。 – jleeothon
'args'和'kwargs'都不是特别的,只是传统的元组和字典! – cdonts