Siempre llega ese día en el que necesitas tener un demonio funcionando en una máquina. Y cuando llegas ves que necesitas hacer un par de forks, cosas con stdin y stdout… un peñazo, por suerte en python existe una librería llamada python-daemon, aunque no está demasiado bien documentada (hay que bucear un poco en los fuentes), es muy útil para no tener que liarte demasiado para hacer el demonio. Aquí demo un ejemplo de uso de python-daemon con su log y sus redirecciones de los std*.
Para ejecutar el demonio se usa el interfaz típico de start | stop | restart, por ejemplo: |
$ python daemon.py start
Cada lenguaje tiene sus herramientas, su forma de trabajar, sus reglas de estilo, etc… aparte cada uno tenemos nuestros pequeños trucos y reglas para trabajar lo más ordenado posible. Por ello voy a dar una serie de consejos que he ido aprendiendo a medida que he ido programando en python que espero puedan ser de utilidad a otras personas que así lo hagan.
- Sigue las reglas de python. Para conocerlas basta con que ejecutes python -c “import this” en la consola. No son específicas python, creo que sirven para cualquier lenguaje, muy recomendable “lectura”.
- Trata de seguir las recomendaciones de la guía de estilo del PEP-008 (Style Guide for Python Code). Los PEP (Python Enhancement Proposals) son documentos que se redactan y siguen cuando se implementa una nueva característica.
- Aprovecha la potencia del lenguaje. Si sabes ruby o similar sabrás de lo que hablo, los que vienen de java, C, C++ están acostumbrados a lenguajes más bien estáticos, se usa poco la metaprogramación. Python tiene cosas muy interesantes, por ejemplo las list comprehesions que agilizan mucho el desarrollo. Siempre con mucho cuidado de no pasarse (la gente de ruby me entenderá). Por ejemplo, la gente que viene de java suele escribir interfaces y luego heredar para a implementación. En python directamente usa duck typing.
- Cuidado con los imports. Salvo que sepas lo que haces trata de no hacer “from module import *”. Primero porque si lo haces posiblemente es que no sepas ni lo que quieres usar, segundo porque puede ser una fuente de bugs importante. Es mejor hacer “from module import MyClass, MyClass2”. A mi me gusta primero poner los imports de la librería estandard y después lo propios de la aplicación, pero es algo personal.
- Unicode: siempre especifica la codificación del fichero, en el pep-0263 tienes toda la información, pero el resumen es, pon la siguiente cabecera:
#!/usr/bin/python
# -*- coding: -*-
Si no lo haces tarde o temprano tendrás alguna excepción al ejecutar tu código por haber puesto caracteres fuera del ascii. Además, trata de entender como qué es unicode, como se hace para usarlo en python.
- Excepciones. No captures una excepción y no hagas nada. La gente que programa en java lo puede hacer (y de hecho lo hace), pero si eres un hombre de bien haz algo. Captura la excepción que corresponde, esto es, si esperas un socket.error no pongas un except que recoja a troche y moche, solo captura esa excepción.
- Las doctest son una verdadera virguería para documentar a la vez que testear. No en todos los sitios se pueden usar, pero por ejemplo si al comienzo de un módulo pones una explicación usando doctest mejorará bastante, por ejemplo:
”””
Este módulo sirve para sumar 3 números usando la función add3.
Un ejemplo de uso es:
>>> add3(1,2,3)
6
“”””
def add3(….
Luego desde la consola puedes hacer:
python -m doctest modulo.py
y ver si algo casca. Más información de doctest y ejemplos. Además luego hay el módulo unittest, hay frameworks para stubs y mocks, helpers para facilitar los test como nose y pytest, todo lo necesario para estar a la última moda del TDD.
- usa la consola. Unas de las cosas más útiles es que tienes la consola siempre a mano para probar cosillas. La mayoría de las veces no me acuerdo como hacer algo, en la consola lo pruebas instantaneamente. Recomiendo usar ipython, que viene ser igual que la consola original python, pero con facilidades para acceder a la documentación, autocompletado, etc.
- Usar pip o easy_install. Es similar a gem en ruby, lo que hace es instalar módulos de terceros desde internet con un solo comando. Esto es fundamental y agiliza el desarrollo muchísimo. Para buscar el software usa Python Package Index donde tú mismo puedes subir tus paquetes. De hecho el paquete de la librería standard para empaquetar módulos lo sube automáticamente con un comando. Prefiero pip a easy_install porque pip está construído con más lógica (tiene uninstall) y más características que cuento dos puntos más abajo.
- Haz pequeños módulos y empaqueta. Empaquetar es súmamente sencillo, con hacer un fichero setup.py con pocos parámetros tienes el empaquetado hecho. Aparte de los benficios que tiene separar las aplicaciones en modulos, tiene otros muy interesantes. El módulo que se usa para estas cosas es distutils, donda hay un ejemplo de setup.py muy sencillo.
- Usa pip. Sí, es repetido, pero pongamos que tienes el caso que has separado tu aplicación en varios módulos que tienes en un repositorio. Desarrollas una aplicación que los necesita, pip te va a ayudar a resolver este problema ya que puede instalar módulos directamente del repositorio (siemre que tengan su setup.py), por ejemplo:
pip install svn+https://mirepo/project/module#egg=module
Todos los paquetes necesarios se pueden poner en un fichero requirements.txt que todas las aplicaciones tengan.
- virtualenv. Herramienta fundamental, permite aislar entornos de ejecución. Puedes crear tantos entornos como quieras, cada uno con una versión de python diferente, cada uno con sus librerías. Esta herramienta es, repito, fundamental. Yo lo uso junto a virtualenvwrapper que simplifica la creación y gestión de entornos. Además junto con pip hacen el combo perfecto. Por ejemplo, para tener un entorno de trabajo funcionando basta con hacer:
pip install -E env -r requirements.txt
pip creará un entorno nuevo, e instalará todo los especificado en el fichero requirements.txt, bajándose lo necesario. Luego basta con activar el entorno y a trabajar:
. ./env/bin/activate
- Aprender a usar el debugger, pdb. Sé que ya no mola hacer debug en la línea de comando, que eclipse te lo da todo mascadito, pero si estás en un servidor remoto es útil cuando solo tienes ssh y vim :).
- Usa el log. Python tiene un módulo llamado logging, úsalo, luego se puede configurar para redireccionar a un fichero, al syslog, a stdout. Tiene las típicas error, info, debug… pero lo importante es que lo uses.
En general, cuando no sé la mejor forma de hacer algo, suelo ir al código de la librería standard y mirar paquetes que suelo usar.
Echando un ojo a la closing de la pycon de este año leo la siguiente frase:
I’ve always found a way to use Python as a strategic weapon, a tremendous source of leverage, to make that small group of people much more productive than the big companies that can— through the force of sheer mass— crush you like a bug.
Como algunos sabéis, estamos desarrollando una aplicación para que los agricultores puedan llevar la trazabilidad de sus explotaciones agrícolas. Ya existen aplicaciones que hacen esto, pero son caras, complicadas y hacen demasiadas cosas.
Esta semana se celebra una de las ferias más importantes de agricultura, se celebra cada dos años y reune a una gran cantidad de agricultores. No tenemos stand así que nos hemos hecho unas camisetas con en logo de agrotrack y vamos a ir unos cuantos a ver que se cuece por la feria.
No es algo que creo que tenga repercusión, pero sí puede estar bien como experimento, veremos a ver si tiene impacto en el número de visitas, correos y suscripciones.
Por otro lado vamos avanzado muy rápido con el desarrollo, además tenemos la ventaja de ya tenemos mucho contacto con agricultores y una buena base de datos con los que probar.
Leía el postmoreten de NyxQuest, que para el que no lo sepa es un videojuego creado por una compañía Española, overthetopgames, con gran éxito internacional en wiiware, y he visto ciertas frases que me han gustado mucho, sobretodo porque encajan bastante con la filosofía de tener recursos acotados para obtener mejores resultados.
Since we didn’t have a lot of money to spend, we had to find ways to resolve some problems. Not enough work force for animation? Ask a friend with free time! No budget for voices? Get a voice actress girlfriend with her own studio! No testing department? Friends and family
Since we were a small team and couldn’t have a lot of detailed models and textures, we chose a style that focused on lighting and shadows.
At the same time, we were telling the story of a burned and forgotten earth, full of deserts and ruins… this setting was not only chosen because of the story, it helped us to reduce work. Since the game world was ruined and deserted, we could create fewer assets and spend the time on making them stylish.
We decided to partner and fund the game with our own money. In the end this has worked very well, because we managed to do a good looking game in the time we had, and with scarce resources. But it was a very tight development cycle; we barely made it with the money we had saved.
El artículo es altamente recomendable y merece la pena leerlo detenidamente.