如何通过python-C api将切片对象的元组传递给C.

时间:2014-04-22 08:30:35

标签: python c python-c-api

我在c中使用了一个2d矩阵类,我在python中使用。我希望能够通过传递一个切片对象元组来调用矩阵类,例如A [1:2,1:2]。到目前为止,我所拥有的是以下内容。 __getitem__方法的相关C代码类似于

   int __getitem__(PyObject *slices){       // get tuple of slice objects
       PyObject* slice1;                    // declare first slice object
       PyObject* slice2;                    // declare second slice object       
       slice1 = PyTuple_GetItem(slices, 0); // get first slice from tuple
       slice2 = PyTuple_GetItem(slices, 1); // get second slice from tuple

        // get start and stop of first slice (currently the following three lines do not work)  
        Py_ssize_t start, stop, step, length; 
        PySlice_GetIndicesEx(slice1,length,&start,&stop,&step); 

     return PySlice_Check(slice2) ; 
    } 

此代码使用PySlice_Check方法检查slice2是否确实是切片对象。如果我发表评论PySlice_GetIndicesEx(slice1,length,&start,&stop,&step),我会按预期获得1。但是,如果我留下这一行,我会收到一个错误:

cannot convert 'PyObject* {aka _object*}' to 'PySliceObject*' for argument '1' to 'int PySlice_GetIndicesEx(...

这意味着我无法将slice1或slice2传递给PySlice_GetIndicesEx,因为它需要PySliceObject个对象。

如何正确解开切片对象,以便将其传递给PySlice_GetIndicesEx.此函数接收PySliceObject而不是PyObject,这就是slice1和slice2,即使PySlice_Check(slice1)PySlice_Check(slice2)都返回1.

2 个答案:

答案 0 :(得分:1)

这是解决方案,感谢A. Taggart。:

int __getitem__(PyObject *slices){
    PyObject* slice1;
    PyObject* slice2;    
    slice1 = PyTuple_GetItem(slices, 0);
    slice2 = PyTuple_GetItem(slices, 1);

    Py_ssize_t len = 0, start1 = 0, stop1 = 0, step1 = 0, slicelength1 = 0;
    Py_ssize_t start2 = 0, stop2 = 0, step2 = 0, slicelength2 = 0;
    len = (*self).size() // or however you get the length of the slice
    PySlice_GetIndicesEx((PySliceObject*)slice1,len,&start1,&stop1,&step1,&slicelength1);
    PySlice_GetIndicesEx((PySliceObject*)slice2,len,&start2,&stop2,&step2,&slicelength2);

return 0;

这里的关键是传递(PySliceObject*)slice1,它将切片对象作为PySliceObject传递。

答案 1 :(得分:0)

__getitem__获取一个参数,在您的情况下是两个切片对象的元组。 这意味着,在C *切片中指向一个元组,包含一个带有切片对象的元组。

   PyObject* indices;                   // the indices object
   PyObject* slice1;                    // declare first slice object
   PyObject* slice2;                    // declare second slice object       
   indices = PyTuple_GetItem(slices, 0);
   slice1 = PyTuple_GetItem(indices, 0); // get first slice from tuple
   slice2 = PyTuple_GetItem(indices, 1); // get second slice from tuple