Foro de elhacker.net

Programación => Scripting => Mensaje iniciado por: rponceaci4 en 5 Noviembre 2010, 16:45 pm



Título: [Python] modulo de C para python
Publicado por: rponceaci4 en 5 Noviembre 2010, 16:45 pm
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


Título: Re: [Python] modulo de C para python
Publicado por: Novlucker en 5 Noviembre 2010, 17:19 pm
Cython (http://www.cython.org/) 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


Título: Re: [Python] modulo de C para python
Publicado por: [Zero] en 5 Noviembre 2010, 18:06 pm
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:

Código:
http://wiki.cython.org/Installing

Cython cuenta con una amplia documentación donde explica como construir extensiones y las especificaciones de Cython:
Código:
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
Código
  1. #include <windows.h>
  2. int cMsg(char* lpText,char* lpTitle);
  3.  

ejemplo.c
Código
  1. #include "ejemplo.h"
  2.  
  3. int cMsg(char * lpText,char* lpTitle)
  4. {
  5. return MessageBoxA(0,lpText,lpTitle,0);
  6. }
  7.  

Ahora crearemos un archivo de código Cython llamado ejemplo.pyx con el siguiente contenido:
ejemplo.pyx
Código
  1. cdef extern from "ejemplo.h":
  2. int cMsg(char* lpText,char* lpTitle)
  3.  
  4. def Msg(text,title):
  5.  
  6. #Aquí nos aseguramos de que los parámetros pasados a cMsg desde python son de tipo str
  7. if not isinstance(text,unicode):
  8. if not isinstance(text,str):
  9. raise ValueError("'text' requires text input, got %s" % type(text))
  10. utext=text.encode('UTF-8')
  11.  
  12. if not isinstance(title,unicode):
  13. if not isinstance(title,str):
  14. raise ValueError("'title' requires text input, got %s" % type(text))
  15. utitle=title.encode('UTF-8')
  16.  
  17. #Llamamos a la función definida en ejemplo.h
  18. ret=cMsg(utext,utitle)
  19.  
  20. # if ret==0:
  21. # raise WindowsError("invalid args?")
  22.  
  23. #Retornamos lo devuelto por cMsg
  24. return ret
  25.  

Ahora creamos un archivo setup.py con el siguiente contenido:
Código
  1. # Build using the command: setup.py build_ext --inplace
  2.  
  3. from distutils.core import setup
  4. from distutils.extension import Extension
  5. from Cython.Distutils import build_ext
  6.  
  7. setup(
  8.    cmdclass={'build_ext':build_ext},
  9.    ext_modules=[Extension("Ejemplo",sources=["ejemplo.pyx","ejemplo.c"],libraries=["USER32","KERNEL32"])]
  10. )
  11.  

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:
Código:
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


Título: Re: [Python] modulo de C para python
Publicado por: rponceaci4 en 5 Noviembre 2010, 22:30 pm
Gracias, le echare un ojo en estos dias y ya os cuento.

Rafa