2012-05-16 4 views
9

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

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

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

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

ответ

6

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

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

Вы найдете PyArg_ParseTupleAndKeywords() под Python/getargs.c.

+1

Вместо просто API документ C, там является хорошим читаемым резюме на http://docs.python.org/2/extending/extending.html – timbo

2

Чтобы эмулировать следующее питона:

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') 
+0

Weird - я не могу редактировать. Когда вы добавляете функцию «keywords», вы хотите использовать ее как «PyCFunctionWithKeywords», а не «PyCFunction». –

 Смежные вопросы

  • Нет связанных вопросов^_^