[Python] modulo de C para python

Iniciado por rponceaci4, 5 Noviembre 2010, 16:45 PM

0 Miembros y 1 Visitante están viendo este tema.

rponceaci4

Hola, antes que nada me presento ya que soy nuevo en el foro. Mi nombre es Rafa y trabajo regularmento con python, lo utilizo como software de analisis de datos ya que dispone de librerias como pyfits, pyroot.

Os cuento mi problema, llega un momento en mi codigo que tengo que hacer un for dentro de otro , esto no seria nada del otro mundo de no ser porque cada for recorre una longitud de 400 000, por lo que la longitud total seria de 160 000 000 000. He hecho una primera estimacion de tiempo y utilizando el xrange en lugar del range y haciendo  import math en lugar de from math import acos mi codigo tardaria en correr aproximadamente 14 dias. Sin embargo haciendo un calculo similar en root (realmente C) se tarda menos de 5 horas.

Ahora bien... lo suyo seria poder escribir un modulo en C que yo puedo importar a python para que me haga la operacion especifica. He estado revisando la documentacion de python pero no me aclaro ya que todos los ejemplos son para numeros cuando yo trabajo todo con listas.

Bueno... espero que podias ayudarme.

Un saludo

Rafa

Novlucker

Cython te permite escribir modulos en C y portarlos a python :D
Yo apenas he visto códigos, pero en cualquier momento te traigo la caballería, que hay un usuario del foro que había estado haciendo unos modulos y probablemente sea de más ayuda que yo :P

Zeeeroooo! Te necesitan!

Saludos
Contribuye con la limpieza del foro, reporta los "casos perdidos" a un MOD XD

"Hay dos cosas infinitas: el Universo y la estupidez  humana. Y de la primera no estoy muy seguro."
Albert Einstein

[Zero]

#2
Bueno, pues como bien dice Novlucker, yo había intentado/estoy intentando hacer un módulo en C para python que exportara diversas funciones. Según había leído, hacer el módulo directamente en C es bastante engorroso, por lo que lo mejor es utilizar algo como Cython. Lo primero es instalarlo:

http://wiki.cython.org/Installing

Cython cuenta con una amplia documentación donde explica como construir extensiones y las especificaciones de Cython:
http://docs.cython.org/

Ahora te pongo un ejemplo sencillo de como convertir una función en C en un módulo para python, imaginémonos que queremos exportar esta función, definida en ejemplo.h y con el cuerpo en ejemplo.c:

ejemplo.h

#include <windows.h>
int cMsg(char* lpText,char* lpTitle);


ejemplo.c

#include "ejemplo.h"

int cMsg(char * lpText,char* lpTitle)
{
return MessageBoxA(0,lpText,lpTitle,0);
}


Ahora crearemos un archivo de código Cython llamado ejemplo.pyx con el siguiente contenido:
ejemplo.pyx

cdef extern from "ejemplo.h":
int cMsg(char* lpText,char* lpTitle)

def Msg(text,title):

#Aquí nos aseguramos de que los parámetros pasados a cMsg desde python son de tipo str
if not isinstance(text,unicode):
if not isinstance(text,str):
raise ValueError("'text' requires text input, got %s" % type(text))
utext=text.encode('UTF-8')

if not isinstance(title,unicode):
if not isinstance(title,str):
raise ValueError("'title' requires text input, got %s" % type(text))
utitle=title.encode('UTF-8')

#Llamamos a la función definida en ejemplo.h
ret=cMsg(utext,utitle)

# if ret==0:
# raise WindowsError("invalid args?")

#Retornamos lo devuelto por cMsg
return ret


Ahora creamos un archivo setup.py con el siguiente contenido:
Código (python) [Seleccionar]

# Build using the command: setup.py build_ext --inplace

from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext

setup(
   cmdclass={'build_ext':build_ext},
   ext_modules=[Extension("Ejemplo",sources=["ejemplo.pyx","ejemplo.c"],libraries=["USER32","KERNEL32"])]
)


Este archivo se usa como una especie de makefile, donde definimos el nombre de la extensión ("Ejemplo"), los archivos que contienen el código y las librarías que usa nuestro código en C.

Sólo queda construír el módulo, si hicimos todo bien basta con ejecutar el siguiente comando en la shell:
python setup.py build_ext --inplace

Eso debería generarnos un archivo llamdo ejemplo.pyd, que debería de poder ser importado desde cualquier código python  :P. Si tienes algún problema sólo dilo, es posible que haya cometido algún error ya que no tengo python instalado y no pude probar los códigos, si te falla lo instalo y vemos qué es lo que falla.

Saludos

"El Hombre, en su orgullo, creó a Dios a su imagen y semejanza.”
Nietzsche

rponceaci4

Gracias, le echare un ojo en estos dias y ya os cuento.

Rafa