关于python:PyArg_ParseTupleAndKeywords如何工作?

How does PyArg_ParseTupleAndKeywords work?

我一直在尝试学习如何为python编写C扩展,并希望确保我了解pyarg_parsetupleandkeywords是如何工作的。

我相信第一个参数是一个PyObject指针,它指向按传递顺序传递到C扩展函数的参数数组。第二个参数是传递的关键字列表,传递它们的位置,很可能是某种指示标志,指示关键字在哪个位置开始,位置变得不相关。

然后,pyarg_parsetupleandkeywords使用其关键字列表(第4个参数)在用关键字指定的参数和格式字符串(第3个参数)以及应将相应值复制到的C变量地址(第5个&;+参数)之间进行映射。

我的理解正确吗?当我阅读在线文档时,我看到的只是对"位置参数和关键字参数"的引用,这让我感觉有点不知所措。处理pyarg_parsetupleandkeywords的python解释器的文件在哪里?


要在python中模拟以下内容:

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

以下内容有效:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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
", a);
    printf("b is %s
", b);
    printf("foo is %s
", foo);
    printf("bar is %s
", bar);
    printf("baz is %s
", baz);

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

并使用它:

1
2
3
4
5
6
7
8
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')


你读过http://docs.python.org/c-api/arg.html的开场白了吗?它很好地解释了正在发生的事情。不要直接引用PyArg_ParseTupleAndKeywords的特定参考;它假定您阅读了上面的文本,并且本身并没有太大帮助。

不过,你已经快拿到了。第一个参数实际上是传入位置参数的列表。第二个是传入关键字参数的映射(将给定关键字名称映射到给定值)。第四个参数实际上是您的函数准备接受的关键字列表。是的,第3个参数是格式字符串,第5个和更高版本是复制值的C指针。

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