2016-01-06 33 views
0

我試圖寫一個python3 C-擴展模塊被錯誤地稱爲,說foo,我試圖定義,可以採取關鍵字參數的方法。PYCFunctionWithKeywords被蟒蛇

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; 
} 

當我嘗試這條巨蟒之內,我收到以下錯誤

>>> 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) 

好像解釋沒有在PyMethodDef註冊METH_KEYWORDS標誌。有沒有其他方法可以將PyCFunctionWithKeywords方法添加到Python3中的C擴展中。我發現的唯一來源是this計算器後可以追溯到Python文檔here

任何幫助深表讚賞

回答

1

你沒有定義的所有關鍵字。即使參數是不可選的,它仍然需要有一個名稱定義,因此它可以通過關鍵字或傳遞位置上(等PyArg_ParseTupleAndKeywords可以匹配關鍵字的位置,以防可選參數在位置上通過)。基本上,關鍵字名稱的數量必須始終與要解析的參數的最大數量相匹配。

變化:

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

到:

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

很明顯,你可以命名任何你想要的第一個參數;我只匹配了C變量名稱。

+0

感謝ShadowRanger。我只是通過查看Python中的代碼來自己找出答案。 –