True *args and **kwargs in Python C extension
我正在开发python 3 c扩展。
我可以得到等价的或任意的位置或关键字参数吗?
例如,在python中,我可以写:
1 2 3 4 | def fun(name, parent, *args, **kwargs): # do something with name and parent # do something with args and kwargs pass |
但是我在C语言中找不到一个简单的等价物。虽然我们可以用
采取:
1 2 3 4 5 6 7 8 9 10 11 | 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 */ } |
号
我能想到的"手动"方法大致如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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中,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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; } // … } |
该函数在
这意味着您可以同时使用元组和dict API,或者使用迭代器协议对这些对象中的项进行迭代。