PyArg_ParseTuple的正确用法是什么?

时间:2012-11-29 23:30:45

标签: python python-2.7 python-extensions pyobject

我使用的似乎是PyArg_ParseTuple的确切版本,但代码仍无法正常工作。我正在使用python 2.7

这是我正在编写的Python扩展的C代码:

static PyObject* tpp(PyObject* self, PyObject* args)
{
PyObject* obj;
PyObject* seq;
int i, len; 
PyObject* item;
int arrayValue, temp;

if (!PyArg_ParseTuple(args, "O", &obj)){
    printf("Item is not a list\n");
    return NULL;
}
seq = PySequence_Fast(obj, "expected a sequence");
len = PySequence_Size(obj);
arrayValue = -5;
printf("[\n");
for (i = 0; i < len; i++) {
    item = PySequence_Fast_GET_ITEM(seq, i);
    // printf("%d : %d, PyArg: ", item, *item);
    // PyArg_ParseTuple(item, "I", &temp);

    PyObject* objectsRepresentation = PyObject_Repr(item);
    const char* s = PyString_AsString(objectsRepresentation);
    printf("%s\n", s);


    PyObject* objType = PyObject_Type(item);
    PyObject* objTypeString = PyObject_Repr(objType);
    const char* sType = PyString_AsString(objTypeString);
    printf("%s\n", sType);

    if (PyArg_ParseTuple(item, "i", &arrayValue) != 0){
        printf("%d\n", arrayValue);
        printf("horray!\n");
    } 
}
Py_DECREF(seq);
printf("]\n");
printf("Item is a list!\n");
Py_RETURN_NONE;
}

然后我只是构建扩展并转到终端     进口等  然后     et.tpp([1,2]) 无法打印该行     if(PyArg_ParseTuple(item,“i”,&amp; arrayValue)!= 0){         printf(“%d \ n”,arrayValue);         的printf( “horray \ n!”);     }

我检查了代码中的类型,列表中元素的类型,并打印'int'。但由于某些原因,PyArg_ParseTuple有错误。

我需要能够从python中的列表中访问信息以复制一些数据,将其传递给我在其他地方的C代码,然后将结果返回给python。

非常感谢你!

2 个答案:

答案 0 :(得分:2)

答案是使用long PyInt_AsLong(PyObject *io)

&#34; long PyInt_AsLong(PyObject *io)首先尝试将对象强制转换为PyIntObject(如果它还不是),然后返回其值。如果有错误,则返回-1,并且调用者应检查PyErr_Occurred()以查明是否存在错误,或者该值是否恰好为-1。&#34;

这是来自http://docs.python.org/2/c-api/int.html这是官方的c python int对象文档,其中包含所有相关方法。

不幸的是,这只返回一个很长的值。但是,如果预期值很小,那么简单的强制转换就足够了。

答案 1 :(得分:1)

PyArg_ParseTuple()仅用于解析元组,顾名思义。在您的代码中,item是一个int,而不是一个元组。要将int对象转换为C值,您需要使用arrayValue = PyInt_AsLong(item)。请注意,它返回的是C long,而不是int,因此您应将arrayValue声明为long

(编辑:之前我错误地提到了PyInt_FromLong。)