Módulos en C para Python

Traducción de Anatomy of a Python C Module

Escribir módulos C en Python es relativamente fácil. La razón principal para hacer esto es incrementar el rendimiento de un código en Python. A continuación se demostrará como implementar la siguiente función de Python en C. Esta función puede encontrarse aquí:

    def fib2(n): # return Fibonacci series up to n
    """Return a list containing the Fibonacci series up to n."""
    result = []
    a, b = 0, 1
    while b < n:
        result.append(b)    # see below
        a, b = b, a+b
    return result

Cabe destacar que esta no es una función particularmente lenta -en realidad es bastante rápida- Simplemente tiene una serie de aspectos interesantes para implementar un modulo C en Python, como la creación de una lista de Python en C. El ejemplo de la creación de un modulo C para Python no es tan amplio como podría llegar a serlo, si todo va bien la implementación de la secuencia Fibonacci en C resultará un poco más explicativa.

Para empezar siempre se incluye Python.h:

#include Python.h;

Lo siguiente será crear la función fib. Primero definimos la función como un Python Object, al que se le pasaran argumentos:

static PyObject *
fib(PyObject *self, PyObject *args)
{

Después una vez en el cuerpo de la función inicializamos algunas variables:

   int a = 0, b = 1, c, n;

Entonces será cuando se realice el analisis de los parámetros proporcionados a la función. Para esto se utilizar  PyArg_ParseTuple. Puede encontrar mas documentación en Parsing arguments and building values, que dará una visión general sobre como analizar diferentes tipos de parámetros. De todos modos en este ejemplo solo se acepta un único valor entero. Si esto no funciona se devolverá NULL.

if (!PyArg_ParseTuple(args, "i", &n))
    return NULL;

Después se instanciará una nueva lista Python, utilizando PyList_New, que aceptará un número entero como longitud de la lista. Ya que se desconoce fual será la longitud se empezará con cero.

PyObject *list = PyList_New(0);

A continuación están las entrañas del verdadero cálculo. Se debe prestar atención a la sentencia PyList_Append(list, PyInt_FromLong(b));, ya que es donde añadimos un nuevo item a la lista. PyList_Append es analogo al metodo de Python list.append(). Se utiliza PyInt_FromLong para crear un objeto Python con un entero dentro del bucle.

while(b < n){
    PyList_Append(list, PyInt_FromLong(b));
    c = a+b;
    a = b;
    b = c;
}

Y entonces se devuelve la lista:

    return list;
}

Esto conforma las entrañas de la funcion, pero como integrar esto en Python como un módulo? Primero debe crearse un objeto PythonMethodDef con las funciones que quieren incorporarse al modulo. Ya que solo tenemos una función solo tenemos que añadir una definición, como esta:

PyMethodDef methods[] = {
    {"fib", fib, METH_VARARGS, "Returns a fibonacci sequence as a list"},
    {NULL, NULL, 0, NULL}
};

El último paso es inicializar el módulo. Para entender que ocurre en esta parte debe leerse esta página que contiene una explicación completa del proceso.

PyMODINIT_FUNC
initfib()
{
    (void) Py_InitModule("fib", methods);
}

Ahora que el modulo en C para Python esta completo, tiene que compilarse. La forma más fácil de hacerlo es utilizar el módulo distutils. Creamos setup.py como sigue:

from distutils.core import setup, Extension

setup(name = "Fib",
      version = "1.0",
      ext_modules = [Extension("fib", ["fib.c"])])

Con eso se informa a distutils que nuestro modulo esta ubicado en fib.c. Ahora se ejecuta:

$ python setup.py build
$ python setup.py install

Y ya está instalado, para utilizarlo debemos importar el módulo y utilizar la función:

import fib
fib.fib(123)
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

Una secuencia fibonacci es fácil de calcular, y hacerlo en C es un ejercicio para mostrar como se pueden implementar funciones y módulos en C. Aun así, y aunque no sea compleja, la versión en C es cuatro veces más rápida que su equivalente en Python. Este simple ejemplo debería mostrar como de fácil -y útil- es implementar extensiones en C

Hay mucho mñas sobre este procedimiento en Extending and Embedding the Python Interpreter que recomiendo leer.

3 Comentarios

  1. milad

    رزرو تور کیش ، تور کیش ارزان و تور کیش لحظه آخری با بهترین قیمت ها شامل تور کیش از تهران ، تور کیش از مشهد ، تور کیش از شیراز ، و تور کیش از اصفهان ، با بلیط چارتر هواپیما و ترنسفر رایگان
    https://www.kishlandyar.com/kish-tours

Dejar un comentario

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