En los últimos tiempos estoy vendiendo mi alma al diablo y he empezado a usar Python. Personalmente prefiero Perl, Python me parece un lenguaje más anárquico y desorganizado. Sin embargo, Python está de moda en Bioinformática y muchos de los módulos más actualizados se están escribiendo en este lenguaje.
Hoy voy a hablar del problema que me he encontrado para encontrar un módulo que procese las opciones de línea de comandos que normalmente introducimos en los scripts, por ej.: ./script.py -i archivo1 -o archivo2 Estas opciones suelen ser archivos de entrada, salida, o simplemente parámetros que cambian la ejecución del programa. También sirve para pedir ayuda sobre como usar el script: ./script.py -h
En Perl existe el módulo Getopt::Long para procesar dichos parámetros de línea de comando de una forma sencilla y robusta.
En Python el módulo equivalente es getopt. A continuación se muestra un ejemplo de uso. Sin embargo este módulo no contempla la posibilidad de procesar múltiples opciones para un mismo argumento, por ejemplo, varios archivos de entrada.
Para solucionar este problema de Python de procesar argumentos de línea de comandos con múltiples opciones he creado mi propio código, puesto que me parece fundamental para cualquier script bioinformático. En el siguiente ejemplo se pueden definir listas para guardar múltiples opciones para un único argumento (ej. varios archivos). El código es provisional y le faltarían muchas opciones que sí tiene el módulo getopt, sin embargo, ofrece una solución al problema y espero ir mejorándolo con el tiempo.
Hoy voy a hablar del problema que me he encontrado para encontrar un módulo que procese las opciones de línea de comandos que normalmente introducimos en los scripts, por ej.: ./script.py -i archivo1 -o archivo2 Estas opciones suelen ser archivos de entrada, salida, o simplemente parámetros que cambian la ejecución del programa. También sirve para pedir ayuda sobre como usar el script: ./script.py -h
En Perl existe el módulo Getopt::Long para procesar dichos parámetros de línea de comando de una forma sencilla y robusta.
En Python el módulo equivalente es getopt. A continuación se muestra un ejemplo de uso. Sin embargo este módulo no contempla la posibilidad de procesar múltiples opciones para un mismo argumento, por ejemplo, varios archivos de entrada.
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Script que usa el módulo 'getopt' para parsear los argumentos y opciones de línea de comandos
"""
import sys, re, os, copy
# Importar el módulo 'getopt'
import getopt
# Imprimir en pantalla el script y sus argumentos y opciones
print 'ARGV:', " ".join(sys.argv[0:]),"\n"
# Información de ayuda de uso del script
def help() :
"""Ayuda sobre opciones del script en línea de comandos"""
print "usage:",sys.argv[0], "[options]\n"
print " -h this message\n"
print " -i input file/s\n"
print " -o output file\n"
# Definir los argumentos obligatorios (:) y opcionales, en sus formas abreviada y completa
try:
options, args = getopt.getopt(sys.argv[1:], "hi:o:", ["help", "input", "output"])
except getopt.GetoptError as err:
# Imprimir ayuda y salir si hay algún error o argumento incorrecto
print str(err)
help()
sys.exit(2)
output = None
verbose = False
# Definir el tipo de las variables que guardarán las opciones
INP_input = ''
INP_output = ''
# Asignar las opciones a cada argumento
for _opt, _arg in options:
if _opt in ("-i", "--input"):
INP_input = _arg
elif _opt in ("-o", "--output"):
INP_output = _arg
elif _opt in ("-h", "--help"):
help()
sys.exit()
else:
assert False, "unhandled option"
# Imprimir en pantalla todo lo anotado
print "Script:",sys.argv[0],"\n"
print "Argumentos y opciones:\n",
for _opt,_arg in options :
print " -"+_opt+": "+_arg
Para solucionar este problema de Python de procesar argumentos de línea de comandos con múltiples opciones he creado mi propio código, puesto que me parece fundamental para cualquier script bioinformático. En el siguiente ejemplo se pueden definir listas para guardar múltiples opciones para un único argumento (ej. varios archivos). El código es provisional y le faltarían muchas opciones que sí tiene el módulo getopt, sin embargo, ofrece una solución al problema y espero ir mejorándolo con el tiempo.
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Script que parsea los argumentos y opciones de línea de comandos
permitiendo usar listas para guardar argumentos con múltiples opciones
"""
import sys, re, os, copy
from types import *
# Imprimir en pantalla el script y sus argumentos y opciones
print 'ARGV:', " ".join(sys.argv[0:]),"\n"
# Información de ayuda de uso del script
def help() :
"""Ayuda sobre opciones del script en línea de comandos"""
print "usage:",sys.argv[0], "[options]\n"
print " -h this message\n"
print " -i input file/s\n"
print " -o output file\n"
exit()
# Definir el tipo de las variables que guardarán las opciones
INP_input = []
INP_output = ''
# Asignar a cada argumento una de las anteriores variables
options = {'h': 'help', 'help': 'help', 'i': 'INP_input', 'input': 'INP_input', 'o': 'INP_output', 'output': 'INP_output'}
argv_var = str()
# Leer los argumentos y opciones
for _argv in sys.argv[1:] :
# Leer los argumentos que comienzan con guión
if re.match("^-", _argv) :
for _opt,_var in options.iteritems() :
if re.compile("^-%s$" % (_opt)).match(_argv) :
argv_var = copy.deepcopy(_var)
if type(vars()[argv_var]) is FunctionType :
vars()[argv_var]()
break
# Anotar las opciones de cada argumento
else :
if argv_var is not None :
if type(vars()[argv_var]) is ListType :
vars()[argv_var].append(_argv)
else:
vars()[argv_var] += _argv
# Imprimir en pantalla todo lo anotado
print "Script:",sys.argv[0],"\n"
print "Argumentos y opciones:\n",
for _opt,_var in options.iteritems() :
if vars()[_var] is not None and type(vars()[_var]) is not FunctionType:
#print _opt,pprint(type(vars()[_var]))
if type(vars()[_var]) is ListType:
print " -"+_opt+": "+str(", ".join(vars()[_var]))
else :
print " -"+_opt+": "+str(vars()[_var])