如何通过Python-C API将切片对象的元组传递给C

2 投票
2 回答
1197 浏览
提问于 2025-04-18 03:42

我在C语言中有一个二维矩阵的类,现在想在Python中使用它。我希望能够通过传递一个切片对象的元组来调用这个矩阵类,比如说,像这样:A[1:2,1:2]。到目前为止,我的代码如下:

   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,而slice1和slice2是PyObject,尽管PySlice_Check(slice1)PySlice_Check(slice2)都返回了1

2 个回答

0

__getitem__ 是一个方法,它只接受一个参数。在你的例子中,这个参数是一个包含两个切片对象的元组。这意味着在 C 语言中,slices 指向一个包含这两个切片对象的元组。

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

这里的解决方案要感谢 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 传递过去。

撰写回答