Python | Función de extensión operando en Arrays

Escribamos una función de extensión de C que pueda operar en conjuntos de datos contiguos, como podría ser creado por el módulo de array o bibliotecas como NumPy y esta función debe ser de propósito general y no específica para ninguna biblioteca de array.

El código debe usar Buffer Protocol para recibir y procesar arrays de manera portátil. El siguiente código es una función de extensión de C que recibe datos de array y llama a la avg(double *buf, int len)función de este artículo: Uso de códigos C en Python .

Código #1:

/* 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);
}

Código #2: Cómo funciona esta función de extensión

import array
  
print("Average : ", avg(array.array('d', [1, 2, 3])))
  
import numpy
print("Average numpy array : ", avg(numpy.array([1.0, 2.0, 3.0])))
print ("Average list : \n", avg([1, 2, 3]))

Producción :

Average : 2.0

Average numpy array : 2.0
Average list : 
Traceback (most recent call last):
File "", line 1, in 
TypeError: 'list' does not support the buffer interface
  • PyBuffer_GetBuffer()La función es la clave del código en el artículo.
  • Intenta obtener la información sobre la representación de la memoria en el objeto de Python arbitrario dado.
  • Simplemente genera una excepción y devuelve -1, si no es posible obtener información (como es el caso de los objetos normales de Python).
  • Las banderas especiales pasadas para PyBuffer_GetBuffer()dar pistas adicionales sobre el tipo de búfer de memoria que se solicita.
  • Como, PyBUF_ANY_CONTIGUOUS especifica que se requiere una región de memoria contigua.

Publicación traducida automáticamente

Artículo escrito por manikachandna97 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *