Как работает PyArg ParseTupleAndKeywords?

Я пытаюсь научиться писать C-расширения для Python и хочу быть уверенным, что понимаю, как работает PyArg_ParseTupleAndKeywords.

Я считаю, что первый аргумент является указателем PyObject, который указывает на массив аргументов, передаваемых в функцию C-extension в порядке их передачи. Второй аргумент-это список ключевых слов, которые были переданы, позиции, на которых они были переданы и, скорее всего, какой-то флаг индикатора, сообщающий, на каком позиция ключевые слова начинаются и позиция становится неактуальной.

PyArg_ParseTupleAndKeywords затем использует свой список ключевых слов (4-й аргумент) для сопоставления между аргументами, указанными с ключевым словом и строкой формата (3-й аргумент) и адресами переменных C (5-й и + аргументы), в которые должны быть скопированы соответствующие значения.

правильно ли я понимаю? Когда я прочитал в документации, я вижу ссылки на "аргументы и сайта аргументы", которые оставляют меня чувствовать себя немного в темноте. Где находится файл для интерпретатора Python, который обрабатывает PyArg_ParseTupleAndKeywords?

2 ответов


вы прочитали вступительное объяснение в http://docs.python.org/c-api/arg.html ? Это довольно хорошо объясняет, что происходит. Не переходите прямо к конкретной ссылке для PyArg_ParseTupleAndKeywords; Он предполагает, что Вы читаете текст выше, и сам по себе не очень полезен.

ты почти сделала это. Первый аргумент-это действительно список входящих позиционных аргументов. Вторая карта входящих параметров сайта (отображение имени сайта в заданное значение.) Четвертый аргумент-это фактически список ключевых слов, которые ваша функция готова принять. Да, 3-й аргумент - это строка формата, а 5-й и более поздние-указатели C, в которые копируются значения.

вы можете найти PyArg_ParseTupleAndKeywords() под Python/getargs.c.


чтобы эмулировать следующее в 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')