2012-05-16 45 views
9

我一直在努力學習如何爲Python編寫C-extensions,並且想確定我理解PyArg_ParseTupleAndKeywords是如何工作的。PyArg_ParseTupleAndKeywords如何工作?

我相信第一個參數是一個PyObject指針,它指向按照傳遞順序傳遞給C擴展函數的參數數組。第二個參數是傳遞的關鍵字列表,傳遞的位置以及很可能的某種指示標誌,指示關鍵字在哪個位置開始和位置變得無關緊要。

PyArg_ParseTupleAndKeywords然後使用它的關鍵字列表(第四參數)與一個關鍵字和兩個格式字符串(第三參數)指定的參數和C變量的地址(第五& +參數),其適當的值應介於映射覆制。

我的理解是否正確?當我閱讀在線文檔時,我所看到的都是對「位置參數和關鍵字參數」的引用,這讓我感覺在黑暗中有點感覺。 Python解釋器的文件在哪裏處理PyArg_ParseTupleAndKeywords?

回答

6

您是否已通讀http://docs.python.org/c-api/arg.html的開場說明?它很好地解釋了發生了什麼。不要去PyArg_ParseTupleAndKeywords的具體參考;它假定你閱讀了上面的文字,而且本身並不是非常有用。不過,你已經差不多了。第一個參數確實是傳入位置參數的列表。第二個是傳入關鍵字參數的映射(將給定關鍵字名稱映射到給定值)。第四個參數實際上是你的函數準備接受的關鍵字列表。是的,第三個參數是格式字符串,第五個和後面的是指向其中的值的C指針。

您會在Python/getargs.c下找到PyArg_ParseTupleAndKeywords()

+1

而不僅僅是C API文檔,有在http://docs.python.org/2/extending/extending.html – timbo

2

爲了模擬在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') 
+0

是一個很好的可讀摘要奇怪 - 我無法編輯。當你使用「關鍵字」功能時,你想把它轉換成'PyCFunctionWithKeywords',而不是'PyCFunction'。 –