2016-01-06 2 views
0

Я пытаюсь написать модуль C-расширения для python3, скажем foo, и я пытаюсь определить метод, который может принимать аргументы ключевых слов.PYCFunctionWithKeywords неправильно вызывается из python

static PyObject* fooImpl(PyObject*, PyObject*, PyObject*); 
static PyObject* fooImpl2(PyObject, PyObject*); 
static PyMethodDef fooMethods[] = { 
    {"foo_impl", (PyCFunction) fooImpl, METH_VARARGS | METH_KEYWORDS, "Some description"}, 
    {"foo_impl2", fooImpl2, METH_VARARGS, "Some description"}, 
    {NULL, NULL, 0, NULL} 
}; 

PyObject* fooImpl(PyObject* self, PyObject* args, PyObject* kwds) { 
    static const char *keywordList[] = { "kw1", "kw2", NULL}; 
    PyObject *input = nullptr; 
    PyObject *kw1Val = nullptr; 
    PyObject *kw2Val = nullptr; 
    PyObject *returnVal = nullptr; 
    int err = PyArg_ParseTupleAndKeywords(args, kwds, "O|OO", 
              const_cast<char**>(keywordList), 
              &input, &kw1Val, &kw2Val); 
    if (!err) { 
     return NULL; 
    } 
    //// Do something with args to compute returnVal 
    return returnVal; 
} 

Когда я пытаюсь это в Python, я получаю следующую ошибку

>>> import foo as fp 
>>> arg1 = ... 
>>> arg2 = ... 
>>> arg3 = ... 
>>> a = fp.foo_impl(arg1, kw1 = arg2, kw2 = arg3); 
TypeError: function takes at most 2 arguments (3 given) 

Похоже, что интерпретатор не регистрируя METH_KEYWORDS флаг в PyMethodDef. Есть ли другой способ добавить PyCFunctionWithKeywords методы для C-расширения в Python3. Единственный источник я нашел this StackOverflow пост, который восходит к документации Python here

Любая помощь глубоко ценится

ответ

1

Вы не определить все ключевые слова. Даже если аргумент не является необязательным, он все равно должен иметь определенное имя, поэтому его можно передать по ключевому слову или по позициям (и поэтому PyArg_ParseTupleAndKeywords может сопоставлять позиции с ключевыми словами, если необязательные аргументы передаются позиционно). В принципе, количество имен ключевых слов должно всегда соответствовать максимальному количеству аргументов для синтаксического анализа.

Изменение:

static const char *keywordList[] = { "kw1", "kw2", NULL}; 

к:

static const char *keywordList[] = { "input", "kw1", "kw2", NULL}; 

Очевидно, что вы можете назвать первый аргумент, что вы хотите; Я просто сопоставил имя переменной C.

+0

Спасибо ShadowRanger. Я просто сам вычислил ответ, посмотрев код на Python. –

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

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