Parseando argumentos, más allá de argparse

docopt_1 lenguaje de programación python

Al ejecutar una aplicación a través de la línea de comandos, muchas veces no somos conscientes de la enorme cantidad de opciones o parámetros que esta puede admitir. A menudo esto se debe a que prácticamente siempre utilizamos esa aplicación o ese comando de la misma manera (por ejemplo en el caso del cat de UNIX), pero si hacemos el ejercicio de repetir la invocación acompañada de –help (o a veces -h), veremos que normalmente los comandos van acompañados de su buena ristra de opciones.

docopt_1 lenguaje de programación python

A tener en cuenta

Cuando somos meramente usuarios el problema se limita a que tenemos que dedicarle un tiempo a leer y entender la documentación para ver las opciones disponibles. ¿Qué ocurre cuando somos nosotros los que tenemos que desarrollar una aplicación que tenga que recibir una cantidad determinada de parámetros? Existen dos principios básicos a tener en cuenta:

  • Debemos indicar claramente las distintas modalidades de ejecución de nuestra aplicación, de manera que, si el usuario no la utiliza como hemos pensado, el mensaje resultante le informe adecuadamente de cómo hacerlo.
  • Es recomendable disponer de una forma fácil de parsear los distintos argumentos de manera que luego podamos utilizarlos en nuestro código.

La librería argparse es una de las más utilizadas para abordar esta tarea y ofrece un abanico muy amplio de posibilidades. Hoy vamos a presentar otra librería, quizá menos conocida pero más intuitiva, que es docopt. En docopt, nosotros solamente tenemos que pensar la clásica descripción de uso (Usage) que encontramos en la mayoría de los comandos o programas. Una vez hayamos definido las distintas modalidades de uso, escribiremos el bloque de texto resultante como un comentario multilínea Python (entre triples comillas dobles). Vamos a ilustrar esto con un sencillo ejemplo. Supongamos que estamos haciendo una calculadora básica en Python capaz de sumar, restar, multiplicar, dividir, hacer potencias y raíces cuadradas.

Ejemplo de usage

Nuestro Usage podría ser algo así:

docopt_2 lenguaje de programación python

Esto es todo lo que necesita docopt para parsear por nosotros los argumentos con los que puede funcionar nuestra aplicación. Como veis, no se puede decir aún que hayamos tirado una sola línea de código :). Ahora sí vamos a meter algo de código (aunque solo sea importar la librería e invocar al método que hará la magia):

docopt_3 lenguaje de programación python

A partir de esto, ya podemos probar a ejecutar el código, lo hemos llamado metido en un fichero que hemos llamado calculator.py.

Ahora pueden ocurrir tres cosas:

La primera (y más habitual) es que el usuario que ejecute por primera vez la aplicación vaya a ciegas y no la invoque como nosotros esperamos, por ejemplo con un simple python calculator.py:

docopt_4 lenguaje de programación python

Vemos cómo, automáticamente, se nos muestra cuáles son las posibles formas de uso de calculator.py.

La segunda es que nuestro usuario pruebe a utilizar el típico parámetro -h o –help para informarse de las modalidades de ejecución:

docopt_5 lenguaje de programación python

Obteniendo también el resultado deseado (podemos probar también con –version para ver cómo nos informa de la versión de nuestra aplicación, esto es posible gracias a que hemos rellenado el parámetro correspondiente al invocar el método docopt).

Finalmente la tercera es que nuestro usuario sepa cómo ejecutar la aplicación, en este caso docopt almacenará por nosotros todos los posibles parámetros en un diccionario de Python (fijaos que anteriormente añadimos un print(arguments) para poder ver cómo docopt ha dispuesto nuestros argumentos en un diccionario)

docopt_6 lenguaje de programación python

A partir de aquí ya es nuestra labor hacer lo que queramos con los argumentos, referenciándolos como cualquier elemento de un diccionario, por ejemplo:

docopt_7 lenguaje de programación python

Conclusión

Esto es solo una muestra de las opciones que nos ofrece docopt para construir nuestro Usage (realmente soporta las definidas en el estándar IEEE Std 1003.1 más conocido como POSIX). Si queréis probarlo, bastará con que lo instaléis mediante pip install docopt en vuestro entorno (está probado desde la versión de Python 2.6 a la 3.5).

¡Feliz parseo!


Alejandro Arranz, Data Engineer en datahack

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *