Encapsulando Python en un binario

| Publicado: | Código fuente

Este es un lindo truquito que no es de mi autoría, sino que es de John Lenton (él lo mostró en una reunión del laburo), pero como yo ya lo mostré en PyCon Brasil el año pasado, y en PyCon Argentina ayer, lo pongo acá para el que lo quiera mirar...

Arrancamos con nuestro programa o proyecto Python que queremos meter adentro del binario... para nuestro ejemplo acá, crearemos un directorio, lo hacemos paquete de Python, y adentro creamos lo que sería el programa principal de nuestro sistema, con una función adentro que es la que arrancaría todo:

[email protected]:~/prueba$ mkdir proyecto
[email protected]:~/prueba$ cd proyecto/
[email protected]:~/prueba/proyecto$ touch __init__.py
[email protected]:~/prueba/proyecto$ cat principal.py
def run():
    print "Arrancamos!"
[email protected]:~/prueba/proyecto$ cd ..
[email protected]:~/prueba$

Tenemos que probar que podamos arrancar nuestro sistema desde el directorio padre... a veces no es tan fácil, hay que jugar un poquito con los paths de dónde importamos cosas, pero en este ejemplo es sencillo. Pero podemos probarlo facilmente:

[email protected]:~/prueba$ python
Python 2.7.1+ (r271:86832, Apr 11 2011, 18:05:24)
...
>>> import proyecto.principal
>>> proyecto.principal.run()
Arrancamos!
>>>

Una vez que lo logremos ejecutar así, tenemos que poner ese mismo código en un archivo con nombre __main__.py en el directorio padre de nuestro proyecto:

[email protected]:~/prueba$ cat __main__.py
import proyecto.principal
proyecto.principal.run()

Volvemos a probar que nuestro sistema funciona correctamente:

[email protected]:~/prueba$ python __main__.py
Arrancamos!

El próximo paso es meter todo adentro de un archivo ZIP, aprovechando que Python es capaz de interpretar directamente este tipo de archivos comprimidos (por eso el nombre especial de antes, para que Python lo reconozca):

[email protected]:~/prueba$ zip -r proyecto.zip __main__.py proyecto/
 adding: __main__.py (deflated 27%)
 adding: proyecto/ (stored 0%)
 adding: proyecto/__init__.py (stored 0%)
 adding: proyecto/principal.pyc (deflated 45%)
 adding: proyecto/__init__.pyc (deflated 30%)
 adding: proyecto/principal.py (stored 0%)

Probamos nuevamente que, hasta acá, funcione todo correctamente:

[email protected]:~/prueba$ python proyecto.zip
Arrancamos!

Finalmente, metemos todo eso adentro de un binario, indicando que se va a interpretar con Python, y haciéndolo ejecutable:

[email protected]:~/prueba$ ( echo '#!/usr/bin/env python'; cat proyecto.zip ) > miproyecto
[email protected]:~/prueba$ chmod +x miproyecto

¡Ya está! Ahora podemos ejecutar ese binario, como cualquier otro binario, y realmente estaremos ejecutando nuestro proyecto Python:

[email protected]:~/prueba$ ./miproyecto
Arrancamos!

Genial, :)

Comentarios Imprimir