编写扩展函数操作数组-问答-阿里云开发者社区-阿里云

开发者社区> 问答> 正文

编写扩展函数操作数组

哦哦喔 2020-04-17 18:11:08 134

你想编写一个C扩展函数来操作数组,可能是被array模块或类似Numpy库所创建。 不过,你想让你的函数更加通用,而不是针对某个特定的库所生成的数组。

Python
分享到
取消 提交回答
全部回答(2)
  • 景凌凯
    2020-04-17 23:59:34

    在C扩展模块中操作隐形指针:可以参考这篇文章: https://www.baidu.com/link?url=6djl4oF9q-bjXsKIc7n5xA5eoO3YbD_ISURCaytWx9o0B2dmmEhXclgxb_R

    0 0
  • 哦哦喔
    2020-04-17 18:11:16
    为了能让接受和处理数组具有可移植性,你需要使用到 Buffer Protocol . 下面是一个手写的C扩展函数例子, 用来接受数组数据并调用本章开篇部分的 avg(double *buf, int len) 函数:
    
    /* Call double avg(double *, int) */
    static PyObject *py_avg(PyObject *self, PyObject *args) {
      PyObject *bufobj;
      Py_buffer view;
      double result;
      /* Get the passed Python object */
      if (!PyArg_ParseTuple(args, "O", &bufobj)) {
        return NULL;
      }
    
      /* Attempt to extract buffer information from it */
    
      if (PyObject_GetBuffer(bufobj, &view,
          PyBUF_ANY_CONTIGUOUS | PyBUF_FORMAT) == -1) {
        return NULL;
      }
    
      if (view.ndim != 1) {
        PyErr_SetString(PyExc_TypeError, "Expected a 1-dimensional array");
        PyBuffer_Release(&view);
        return NULL;
      }
    
      /* Check the type of items in the array */
      if (strcmp(view.format,"d") != 0) {
        PyErr_SetString(PyExc_TypeError, "Expected an array of doubles");
        PyBuffer_Release(&view);
        return NULL;
      }
    
      /* Pass the raw buffer and size to the C function */
      result = avg(view.buf, view.shape[0]);
    
      /* Indicate we're done working with the buffer */
      PyBuffer_Release(&view);
      return Py_BuildValue("d", result);
    }
    下面我们演示下这个扩展函数是如何工作的:
    
    >>> import array
    >>> avg(array.array('d',[1,2,3]))
    2.0
    >>> import numpy
    >>> avg(numpy.array([1.0,2.0,3.0]))
    2.0
    >>> avg([1,2,3])
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: 'list' does not support the buffer interface
    >>> avg(b'Hello')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: Expected an array of doubles
    >>> a = numpy.array([[1.,2.,3.],[4.,5.,6.]])
    >>> avg(a[:,2])
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ValueError: ndarray is not contiguous
    >>> sample.avg(a)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: Expected a 1-dimensional array
    >>> sample.avg(a[0])
    
    2.0
    >>>
    
    0 0
添加回答
开发与运维
使用钉钉扫一扫加入圈子
+ 订阅

集结各类场景实战经验,助你开发运维畅行无忧

推荐文章
相似问题
推荐课程