PyArg_ParseTupleAndKeywords如何工作?

时间:2012-05-16 20:03:57

标签: python python-c-api python-c-extension

我一直在努力学习如何编写Python的C扩展,并希望确定我理解PyArg_ParseTupleAndKeywords的工作原理。

我相信第一个参数是一个PyObject指针,它指向一个参数数组,这些参数按照它们传递的顺序传递给C-extension函数。第二个参数是传递的关键字列表,它们被传递的位置,以及非常可能的某种指示标记,告诉关键字开始和位置变得无关紧要。

PyArg_ParseTupleAndKeywords然后使用其关键字列表(第四个参数)来映射用关键字指定的参数和格式字符串(第三个参数)和C变量的地址(第5个参数),适当的值应该是复制。

我的理解是否正确?当我阅读在线文档时,我所看到的只是对“位置参数和关键字参数”的引用,这让我感到有些不知所措。处理PyArg_ParseTupleAndKeywords的Python解释器的文件在哪里?

2 个答案:

答案 0 :(得分:8)

在python中模拟以下内容:

def keywords(a, b, foo=None, bar=None, baz=None):
    pass

以下内容可行:


static PyObject *keywords(PyObject *self, PyObject *args, PyObject *kwargs) {
    char *a;
    char *b;
    char *foo = NULL;
    char *bar = NULL;
    char *baz = NULL;

    // Note how "a" and "b" are included in this
    // even though they aren't supposed to be in kwargs like in python
    static char *kwlist[] = {"a", "b", "foo", "bar", "baz", NULL};

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ss|sss", kwlist, &a, &b, &foo, &bar, &baz)) {
        return NULL;
    }

    printf("a is %s\n", a);
    printf("b is %s\n", b);
    printf("foo is %s\n", foo);
    printf("bar is %s\n", bar);
    printf("baz is %s\n", baz);

    Py_RETURN_NONE;
}
// ...
static PyMethodDef SpamMethods[] = {
    //...
    {"keywords", (PyCFunction) keywords, METH_VARARGS | METH_KEYWORDS, "practice kwargs"},
    {NULL, NULL, 0, NULL}

使用它:

from spam import keywords

keywords() // Fails, require a and b
keywords('a') // fails, requires b
keywords('a', 'b')
keywords('a', 'b', foo='foo', bar='bar', baz='baz) 
keywords('a', 'b','foo', 'bar', 'baz')
keywords(a='a', b='b', foo='foo', bar='bar', baz='baz')

答案 1 :(得分:7)

您是否已阅读http://docs.python.org/c-api/arg.html的开场解释?它很好地解释了正在发生的事情。不要直接查看PyArg_ParseTupleAndKeywords的具体参考;它假定你阅读了上面的文字,并且本身并没有很大帮助。

但是,你几乎得到了它。第一个参数确实是传入位置参数的列表。第二个是传入关键字参数的映射(将给定关键字名称映射到给定值)。第四个参数实际上是您的函数准备接受的关键字列表。是的,第三个参数是格式字符串,第五个参数是后面的C指针,值将被复制到其中。

您会在PyArg_ParseTupleAndKeywords()下找到Python/getargs.c