Argumentos de la línea de comandos en Python

A

Visión general

Dado que Python es un lenguaje de programación tan popular, además de tener soporte para la mayoría de los sistemas operativos, se ha vuelto ampliamente utilizado para crear herramientas de línea de comandos para muchos propósitos. Estas herramientas pueden abarcar desde aplicaciones CLI simples hasta aquellas más complejas, como las de AWS awscli herramienta.

Las herramientas complejas como esta suelen ser controladas por el usuario a través de argumentos de la línea de comando, que permite al usuario usar comandos específicos, configurar opciones y más. Por ejemplo, estas opciones podrían indicarle a la herramienta que genere información adicional, lea datos de una fuente específica o envíe la salida a una ubicación determinada.

En general, los argumentos se pasan a las herramientas CLI de manera diferente, según su sistema operativo:

  • Tipo Unix: - seguido de una letra, como -ho -- seguido de una palabra, como --help
  • Windows: / seguido de una letra o una palabra, como /help

Estos diferentes enfoques existen por razones históricas. Muchos programas en sistemas similares a Unix admiten la notación de guiones simples y dobles. La notación de un solo guión se usa principalmente con opciones de una sola letra, mientras que los guiones dobles presentan una lista de opciones más legible, que es particularmente útil para opciones complejas que deben ser más explícitas.

Nota: En este artículo nos centraremos únicamente en el formato similar a Unix de - y --.

Tenga en cuenta que tanto el nombre como el significado de un argumento son específicos de un programa; no existe una definición general, aparte de algunas convenciones comunes como --help para obtener más información sobre el uso de la herramienta. Como desarrollador de un script de Python, usted decidirá qué argumentos proporcionar a la persona que llama y qué hacen. Esto requiere una evaluación adecuada.

A medida que crece su lista de argumentos disponibles, su código se volverá más complejo al tratar de analizarlos con precisión. Afortunadamente, en Python hay varias bibliotecas disponibles para ayudarlo con esto. Cubriremos algunas de las soluciones más comunes, que van desde “hágalo usted mismo” con sys.argv, al enfoque “hecho para usted” con argparse.

Manejo de argumentos de línea de comandos con Python

Python 3 admite varias formas diferentes de manejar los argumentos de la línea de comandos. La forma incorporada es utilizar el sys módulo. En términos de nombres y su uso, se relaciona directamente con la biblioteca C (libc). La segunda forma es la getopt módulo, que maneja opciones tanto cortas como largas, incluida la evaluación de los valores de los parámetros.

Además, existen otros dos métodos comunes. Este es el módulo argparse, que se deriva del optparse módulo disponible hasta Python 2.7. El otro método es usar el docopt módulo, que es disponible en GitHub.

Cada una de estas formas tiene sus pros y sus contras, por lo que vale la pena evaluar cada una para ver cuál se adapta mejor a sus necesidades.

El módulo sys

Este es un módulo básico que se envió con Python desde los primeros días. Toma un enfoque muy similar a la biblioteca C usando argc/argv para acceder a los argumentos. los módulo sys implementa los argumentos de la línea de comando en una estructura de lista simple llamada sys.argv.

Cada elemento de la lista representa un solo argumento. El primer elemento de la lista, sys.argv[0], es el nombre de la secuencia de comandos de Python. El resto de los elementos de la lista, sys.argv[1] a sys.argv[n], son los argumentos de la línea de comandos del 2 al n. Como delimitador entre los argumentos, se utiliza un espacio. Los valores de argumento que contienen un espacio en él deben estar entre comillas para poder ser analizados correctamente por sys.

El equivalente de argc es solo el número de elementos de la lista. Para obtener este valor, use Python len() operador. Mostraremos esto en un ejemplo de código más adelante.

Impresión del primer argumento de CLI

En este primer ejemplo, nuestro script determinará la forma en que se llamó. Esta información se guarda en el primer argumento de la línea de comandos, indexado con 0. El código siguiente muestra cómo obtiene el nombre de su secuencia de comandos de Python.

import sys

print ("The script has the name %s" % (sys.argv[0])

Guarde este código en un archivo llamado argumentos-nombre-programa.py, y luego llámelo como se muestra a continuación. La salida es la siguiente y contiene el nombre del archivo, incluida su ruta completa:

$ python arguments-program-name.py
The script has the name arguments-program-name.py
$ python /home/user/arguments-program-name.py
The script has the name /home/user/arguments-program-name.py

Como puede ver en la segunda llamada anterior, no solo obtenemos el nombre del archivo Python, sino también la ruta completa utilizada para llamarlo.

Contando el número de argumentos

En este segundo ejemplo, simplemente contamos el número de argumentos de la línea de comando usando el len() método. sys.argv es la lista que tenemos que examinar. En el siguiente código, obtenemos el número de argumentos y luego restamos 1 porque uno de esos argumentos (es decir, el primero) siempre se establece como el nombre del archivo, lo que no siempre nos resulta útil. Por lo tanto, el número real de argumentos pasados ​​por el usuario es len(sys.argv) - 1.

import sys

# Count the arguments
arguments = len(sys.argv) - 1
print ("The script is called with %i arguments" % (arguments))

Guarde y asigne un nombre a este archivo argumentos-count.py. A continuación, se muestran algunos ejemplos de cómo llamar a este script. Esto incluye tres escenarios diferentes:

  • Una llamada sin más argumentos de línea de comando
  • Una llamada con dos argumentos
  • Una llamada con dos argumentos, donde el segundo es una cadena entre comillas que contiene un espacio
$ python arguments-count.py
The script is called with 0 arguments
$ python arguments-count.py --help me
The script is called with 2 arguments
$ python arguments-count.py --option "long string"
The script is called with 2 arguments
Iterando a través de argumentos

Nuestro tercer ejemplo genera todos los argumentos enviados al script de Python, excepto el nombre del programa en sí. Por lo tanto, recorremos los argumentos de la línea de comando comenzando con el segundo elemento de la lista. Recuerde que este es el índice 1 ya que las listas están basadas en 0 en Python.

import sys

# Count the arguments
arguments = len(sys.argv) - 1

# Output argument-wise
position = 1
while (arguments >= position):
    print ("Parameter %i: %s" % (position, sys.argv[position]))
    position = position + 1

A continuación, llamamos a nuestro código, que se guardó en el archivo argumentos-output.py. Como se hizo con nuestro ejemplo anterior, la salida ilustra tres llamadas diferentes:

  • Una llamada sin argumentos
  • Una llamada con dos argumentos
  • Una llamada con dos argumentos, donde el segundo argumento es una cadena entre comillas que contiene un espacio
$ python arguments-output.py
$ python arguments-output.py --help me
Parameter 1: --help
Parameter 2: me
$ python arguments-output.py --option "long string"
Parameter 1: --option
Parameter 2: long string

Recuerde, el objetivo de mostrar el ejemplo de cadena entre comillas es que los parámetros generalmente están delimitados por un espacio, a menos que estén entre comillas.

El módulo getopt

Como habrás notado antes, el sys El módulo divide la cadena de la línea de comando en facetas únicas solamente. El python módulo getopt va un poco más allá y amplía la separación de la cadena de entrada mediante la validación de parámetros. Basado en el getopt Función C, permite opciones tanto cortas como largas, incluida una asignación de valor.

En la práctica, requiere sys módulo para procesar correctamente los datos de entrada. Para hacerlo, tanto el sys módulo y el getopt El módulo debe cargarse de antemano. A continuación, de la lista de parámetros de entrada eliminamos el primer elemento de la lista (consulte el código a continuación) y almacenamos la lista restante de argumentos de la línea de comando en la variable llamada argument_list.

# Include standard modules
import getopt, sys

# Get full command-line arguments
full_cmd_arguments = sys.argv

# Keep all but the first
argument_list = full_cmd_arguments[1:]

print argument_list

Los argumentos en argument_list ahora se puede analizar usando el getopts() método. Pero antes de hacer eso, tenemos que decir getopts() sobre qué parámetros son válidos. Se definen así:

short_options = "ho:v"
long_options = ["help", "output=", "verbose"]

Esto significa que estos argumentos son los que consideramos válidos, junto con información adicional:

------------------------------------------
long argument   short argument  with value
------------------------------------------
--help           -h              no
--output         -o              yes
--verbose        -v              no
------------------------------------------

Puede que hayas notado que el o la opción corta fue precedida por dos puntos, :. Esto dice getopt que a esta opción se le debe asignar un valor.

Esto ahora nos permite procesar una lista de argumentos. los getopt() El método requiere que se configuren tres parámetros: la lista de argumentos reales de argv, así como las opciones válidas cortas y largas (que se muestran en el fragmento de código anterior).

La llamada al método en sí se mantiene en una declaración try-catch para cubrir errores durante la evaluación. Se genera una excepción si se descubre un argumento que no forma parte de la lista como se definió anteriormente. La secuencia de comandos de Python imprimirá el mensaje de error en la pantalla y saldrá con el código de error 2.

try:
    arguments, values = getopt.getopt(argument_list, short_options, long_options)
except getopt.error as err:
    # Output error, and return with an error code
    print (str(err))
    sys.exit(2)

Finalmente, los argumentos con los valores correspondientes se almacenan en las dos variables denominadas arguments y values. Ahora, puede evaluar fácilmente estas variables en su código. Podemos usar un for-loop para recorrer la lista de argumentos reconocidos, una entrada después de la siguiente.

# Evaluate given options
for current_argument, current_value in arguments:
    if current_argument in ("-v", "--verbose"):
        print ("Enabling verbose mode")
    elif current_argument in ("-h", "--help"):
        print ("Displaying help")
    elif current_argument in ("-o", "--output"):
        print (("Enabling special output mode (%s)") % (current_value))

A continuación, puede ver el resultado de ejecutar este código. Mostraremos cómo reacciona el programa con argumentos de programa válidos y no válidos:

$ python arguments-getopt.py -h
Displaying help
$ python arguments-getopt.py --help
Displaying help
$ python arguments-getopt.py --output=green --help -v
Enabling special output mode (green)
Displaying help
Enabling verbose mode
$ python arguments-getopt.py -verbose
option -e not recognized

La última llamada a nuestro programa puede parecer un poco confusa al principio. Para comprenderlo, debe saber que las opciones abreviadas (a veces también llamadas banderas) se pueden usar junto con un solo guión. Esto permite que su herramienta acepte muchas opciones más fácilmente. Por ejemplo, llamando python arguments-getopt.py -vh es lo mismo que llamar python arguments-getopt.py -v -h. Entonces, en la última llamada anterior, el getopt módulo pensó que el usuario estaba intentando pasar -e como una opción, que no es válida.

El módulo argparse

los módulo argparse ha estado disponible desde Python 3.2, y una mejora de la optparse módulo que existe hasta Python 2.7. La documentación de Python contiene una descripción de la API y un tutorial que cubre todos los métodos en detalle.

El módulo ofrece una interfaz de línea de comandos con una salida estandarizada, mientras que las dos primeras soluciones dejan gran parte del trabajo en sus manos. argparse permite la verificación de argumentos fijos y opcionales, con la verificación de nombres como estilo corto o largo. Como argumento opcional predeterminado, incluye -h, junto con su versión larga --help. Este argumento va acompañado de un mensaje de ayuda predeterminado que describe los argumentos aceptados.

El siguiente código muestra la inicialización del analizador y la salida a continuación que muestra la llamada básica, seguida del mensaje de ayuda. A diferencia de las llamadas de Python que usamos en los ejemplos anteriores, tenga en cuenta que debe usar Python 3 con estos ejemplos.

# Include standard modules
import argparse

# Initiate the parser
parser = argparse.ArgumentParser()
parser.parse_args()
$ python3 arguments-argparse-basic.py 
$ python3 arguments-argparse-basic.py -h
usage: arguments-argparse-basic.py [-h]

optional arguments:
  -h, --help  show this help message and exit
$ python3 arguments-argparse-basic.py --verbose
usage: arguments-argparse-basic.py [-h]
arguments-argparse-basic.py: error: unrecognized arguments: --verbose

En el siguiente paso, agregaremos una descripción personalizada al mensaje de ayuda para nuestros usuarios. Inicializar el analizador de esta forma permite un texto adicional. El siguiente código almacena la descripción en el text variable, que se da explícitamente a la argparse clase como el description parámetro. Al llamar a este código a continuación, puede ver cómo se ve la salida.

# Include standard modules
import argparse

# Define the program description
text="This is a test program. It demonstrates how to use the argparse module with a program description."

# Initiate the parser with a description
parser = argparse.ArgumentParser(description=text)
parser.parse_args()
$ python3 arguments-argparse-description.py --help
usage: arguments-argparse-description.py [-h]

This is a test program. It demonstrates how to use the argparse module with a
program description.

optional arguments:
  -h, --help  show this help message and exit

Como paso final, agregaremos un argumento opcional llamado -V, que tiene un argumento de estilo largo correspondiente llamado --version. Para hacerlo usamos el método add_argument() que llamamos con tres parámetros (mostrados para --version, solamente):

  • El nombre del parámetro: --version
  • El texto de ayuda para el parámetro: help="show program version"
  • Acción (sin valor adicional): action="store_true"

El código fuente para eso se muestra a continuación. Leer los argumentos en la variable llamada args se realiza a través del parse_args() método del parser objeto. Tenga en cuenta que envía tanto la versión corta como la versión larga en una llamada. Finalmente, verifica si los atributos args.V o args.version se establecen y emiten el mensaje de versión.

# Include standard modules
import argparse

# Initiate the parser
parser = argparse.ArgumentParser()
parser.add_argument("-V", "--version", help="show program version", action="store_true")

# Read arguments from the command line
args = parser.parse_args()

# Check for --version or -V
if args.version:
    print("This is myprogram version 0.1")
$ python3 arguments-argparse-optional.py -V
This is myprogram version 0.1
$ python3 arguments-argparse-optional.py --version
This is myprogram version 0.1

los --version El argumento no requiere que se dé un valor en la línea de comando. Es por eso que establecemos el argumento de acción en "store_true". En otros casos, es posible que necesite un valor asignado adicional, por ejemplo, si especifica un cierto volumen, altura o ancho. Esto se muestra en el siguiente ejemplo. Como caso predeterminado, tenga en cuenta que todos los argumentos se interpretan como cadenas.

# Include standard modules
import argparse

# Initiate the parser
parser = argparse.ArgumentParser()

# Add long and short argument
parser.add_argument("--width", "-w", help="set output width")

# Read arguments from the command line
args = parser.parse_args()

# Check for --width
if args.width:
    print("Set output width to %s" % args.width)

Aquí mostramos lo que sucede al enviar diferentes valores de argumento. Esto incluye tanto la versión corta como la larga, así como el mensaje de ayuda.

$ python3 arguments-argparse-optional2.py -w 10
Set output width to 10
$ python3 arguments-argparse-optional2.py --width 10
Set output width to 10
$ python3 arguments-argparse-optional2.py -h
usage: arguments-argparse-optional2.py [-h] [--width WIDTH]

optional arguments:
  -h, --help            show this help message and exit
  --width WIDTH, -w WIDTH
                        set output width

Conclusión

En este artículo mostramos muchos métodos diferentes para recuperar argumentos de línea de comando en Python, incluido el uso de sys, getopty argparse. Estos módulos varían en funcionalidad, algunos brindan mucho más que otros. sys es totalmente flexible, mientras que tanto getopty argparse requieren algo de estructura. Por el contrario, cubren la mayor parte del trabajo complejo que sys deja en tus manos. Después de trabajar con los ejemplos proporcionados, debería poder determinar qué módulo se adapta mejor a su proyecto.

En este artículo no hablamos de otras soluciones como la docopts módulo, lo acabamos de mencionar. Este módulo sigue un enfoque totalmente diferente y se explicará en detalle en uno de los próximos artículos.

Referencias

About the author

Ramiro de la Vega

Bienvenido a Pharos.sh

Soy Ramiro de la Vega, Estadounidense con raíces Españolas. Empecé a programar hace casi 20 años cuando era muy jovencito.

Espero que en mi web encuentres la inspiración y ayuda que necesitas para adentrarte en el fantástico mundo de la programación y conseguir tus objetivos por difíciles que sean.

Add comment

Sobre mi

Últimos Post

Etiquetas

Esta web utiliza cookies propias para su correcto funcionamiento. Al hacer clic en el botón Aceptar, aceptas el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Más información
Privacidad