Category Archives: python

Ejemplo de proyecto en Python con OO y recomendaciones

El siguiente post contiene un ejemplo de desarrollo de un pequeño proyecto con Python. Este proyecto hace uso de algunos de los elementos de la orientación a objetos en Python, asi como de algunas recomendaciones en el desarrollo con Python.

Que cocinamos

Un pequeño proyecto con Python que incluye lo siguiente:

  • Clases
  • Módulos
  • Paquetes
  • Ficheros de log
  • Tests
  • Documentación autogenerada

El proyecto se puede descargar integro desde https://github.com/luisalbertogh/oopython.git.

Ingredientes

Los requisitos para este proyecto son los siguientes:

Paso a paso

Creamos una estrcutura para el proyecto con el siguiente diseño:

<proyecto>

|__ <config> [ficheros de configuración]

|__ <doc> [documentación]

|__ <proyecto> [código fuente]

|__ <test> [tests de unidad e integración]

Vease el conteido del proyecto a modo de ejemplo.

Código fuente

El código se estructura de la siguiente manera (de más básico a más complejo):

1. Creamos un módulo base que contiene una serie de clases que incluyen nuestro modelo y nuestra lógica de negocio [oopython\mypackage\module01.py]. Aquí encontramos:

Superclases

Clases con diferente tipos de métodos (estáticos, constructores (__init__), sobrecargados (métodos especiales que empiezan con __. etc))

Lazy properties, setters y getters

Clases estratégicas (sin estado, sólo lógica)

2. Incluimos este módulo en un paquete. Esto no es necesario en Python pero puede ser una buena recomendación para modular un poco más y aportar un nivel adicional de granularidad al código desarrollado. Los paquetes estarían compuestos por módulos y estos se podrían usar desde otros módulos y/o paquetes.

Para esto, simplemente creamos el directorio oopython\mypackage, incluimos el módulo recien creado dentro y añadimos un fichero __init__.py. Adicionalmente podemos incluir en el fichero __init__.py otros módulos o paquetes externos o indicar que módulos internos queremos habilitar desde el paquete, de tal manera que sea más sencillo invocarlos cuando se usen desde otros módulos externos. Si añadimos lo siguiente:

Podremos usar el contenido del paquete mypackage desde otros módulos externos simplemente haciendo:

De otra manera tendriamos que especificar el módulo, etc.

3. Creamos un nuevo módulo [oopython\oopython.py] que haga uso del paquete anteriormente creado.

Ficheros de log

Para disponer de una serie de loggers que permitan crear ficheros de log e imprimir mensajes por pantalla, usamos paquetes estandar de logging de Python y YAML como lenguaje para los ficheros de configuración de los mismos.

En caso de que YAML no esté instalado, usar:

En el módulo principal incluimos el siguiente código:

El fichero de configuracion de los logs se encuentra en la ruta config/log_config.yaml. Contiene los valores necesarios para crear differentes tipos de loggers, configurar salidas por consola, formato de los logs, etc.

Tests

Tal y como ocurre en otros lenguajes de programación, aqui también podemos crear tests de unidad y de integración que se ejecuten de forma automática dentro de un proceso de integración continua.

En un directorio separado dentro del proyecto llamado test, creamos diferentes ficheros (módulos) con diferentes grupos de tests. Cada módulo podría ser considerado como un test suite diferente, por ejemplo.

Dentro de cada módulo incluimos diferentes tests unitarios usando el módulo de Python para implementar tests de unidad:

Para que los tests puedan hacer uso de los módulos y paquetes internos del proyecto, se setea la ruta principal del proyecto relativa al test:

Los tests unitarios son métodos del siguiente TestCase:

Los test unitarios se cargan en un único test suite:

Y se ejcutan:

Una manera sencilla de lanzar todos (o los seleccionados) tests es usando el siguiente comando:

Se indica el uso del módulo de testeo de Python y se le indica que ejecute todos los tests unitarios que encuentre en el directorio test correspondiente. También se pueden lanzar como un scrupt de Python sin más.

Generación automática de documentación

La generación automática está basada en el uso de la herramienta Sphinx, que es una de las más extendidas. Los pasos para ejecutarla son basicamente los siguientes:

Instalar Sphinx

http://www.sphinx-doc.org/en/stable/install.html

Ejecutar Sphinx quickstart

Se recomienda seguir este tutorial para concer las opciones más relevantes de este comando. Es importante activar la generación automática de documentación si queremos que la herramienta convierta los comentarios incluidos en el código en Python como texto dentro de la documentación.

http://www.sphinx-doc.org/en/stable/tutorial.html

Revisar valores en conf.py

Antes de lanzar la generación automática de documentación conviene revisar el fichero de configuración autogenerado por el paso anterior. Éste se encuentra en oopython\doc\source\conf.py.

Una de las modificaciones que tenemos que aplicar al fichero recien creado es indicar la ruta en la que se encuentra el código de Python para que los pasos siguientes puedan autogenerar documentación:

De esta manera se añade a la ruta en la que Python busca los módulos y paquetes la ruta que contiene nuestro código.

Sphinx apidoc

Nos permite de forma automática generar los ficheros RST que se usaran para dar formato a la páginas de la documentación que se incluirá asi como su contenido. Normalmente se creara un fichero RST por módulo/paquete y se añadirá información sobre las clases y miembros.

Más información aqui: http://scriptsonscripts.blogspot.com.es/2012/09/quick-sphinx-documentation-for-python.html

El comando de ejecución sería el siguiente. doc/source sería el directorio en el que se generarán los RST y oopython el directorio que contiene el código fuente en Python.

Crear la documentación

Se lanza el siguiente comando:

Y se genera el formato de salida deseado, en este caso en HTML: