¿Desea ejecutar scripts Python con argumentos de línea de comandos? Aprenda a analizar los argumentos de la línea de comandos utilizando los módulos sys, getopt y argparse de Python.
En Python, cuando desee leer la entrada del usuario, utilizará la función input()
. Sin embargo, para algunas aplicaciones, es posible que desee pasar ciertos argumentos mientras ejecuta el script en la línea de comandos.
En este tutorial, aprenderemos a ejecutar un script de Python con opciones y argumentos en la línea de comandos. A continuación, aprenderemos a utilizar los módulos incorporados de Python para analizar dichas opciones y argumentos.
Comencemos
Entendiendo sys.argv en Python
Si ha programado en C, sabrá que una de las formas más sencillas de pasar argumentos al programa es a través de la línea de comandos. Para ello, puede estructurar la función principal de la siguiente manera
#include<stdio.h>
int main(int argc, char **argv){
//argc: contador de argumentos
//argv: vector de argumentos
//hacer algo en los args
devolver 0;
}
Aquí, argc
significa recuento de argumentos y argv
significa vector de argumentos.
Ejecutar scripts Python con argumentos en la línea de comandos
En Python, puede ejecutar el script Python en la línea de comandos utilizando python3 nombrearchivo.py
. Al hacerlo, también puede pasar un número arbitrario de argumentos de línea de comandos:
$ python3 nombrearchivo.py arg1 arg2 ... argn
El módulo sys proporciona soporte «out-of-the-box» para acceder y procesar estos argumentos de línea de comandos. sys.argv
es la lista de todos los argumentos de línea de comandos que pasamos cuando ejecutamos el script Python.
He aquí un ejemplo en el que ejecutamos main.py con argumentos de línea de comandos:
$ python3 main.py hola mundo script python
Podemos hacer un bucle a través del vector de argumentos utilizando un simple bucle for y la función enumerar:
# main.py
importar sys
for idx, arg in enumerate(sys.argv):
print(f "arg{idx}: {arg}")
# Salida
arg0:principal.py
arg1:hola
arg2:mundo
arg3:python
arg4:script
Vemos que el primer argumento (en el índice 0) es el nombre del archivo Python. Y los argumentos siguientes comienzan en el índice 1.
Este es un programa de trabajo mínimo que acepta y procesa argumentos de la línea de comandos. Sin embargo, vemos algunos problemas:
- ¿Cómo saben los usuarios del programa qué argumentos deben pasar?
- ¿Y qué significan estos argumentos?
Esto no está muy claro. Para solucionar esto, puede utilizar los módulos getopt o argparse. Y lo aprenderemos en las próximas secciones.✅
Análisis sintáctico de argumentos en la línea de órdenes utilizando getopt de Python
Aprendamos a analizar argumentos de la línea de órdenes utilizando el módulo getopt incorporado.
Después de importar getopt
del módulo getopt
, puede especificar los argumentos a analizar y las opciones cortas y largas con las que ejecutar el script. Necesitamos analizar todos los argumentos comenzando en el índice 1 de sys.argv
. Así que el trozo a analizar es sys. argv[1:]
.
Aquí, necesitaremos una cadena de mensaje
y un nombre de archivo
. Utilicemos m
y f
como opciones cortas y message
y file
como opciones largas.
Pero, ¿cómo nos aseguramos de que una opción específica requiere un argumento?
- En las opciones cortas, puede hacer que una opción requiera un argumento añadiendo dos puntos (:) después del nombre de la opción corta.
- Del mismo modo, en las opciones largas, puede añadir un signo = después de la opción larga. Podemos capturar estas opciones y sus respectivos argumentos.
Añadiendo esto, tendremos el siguiente código en main.py:
# main.py
import sys
from getopt import getopt
opts, args = getopt(sys.argv[1:],'m:f:',['mensaje=','archivo='])
print(opts)
print(args)
Aquí, la variable opts
contiene las opciones y argumentos como una lista de tuplas. Cualquier otro argumento posicional que pasemos se recogerá en la variable args
.
Podemos pasar el mensaje y el nombre de archivo para ejecutar el script, y podemos utilizar las opciones cortas o las largas.
Ejecutando main.py utilizando las opciones largas, tenemos:
$ python3 main.py --mensaje hola --archivoalgúnarchivo.txt
Tenemos las opciones y los argumentos como tuplas en la variable opts
. Como no hemos pasado ningún argumento posicional, args
es una lista vacía.
# Salida
[('--mensaje', 'hola'), ('--archivo', 'algun-archivo.txt')]
[]
De forma equivalente, también podemos utilizar las opciones cortas como se muestra:
$ python3 main.py -m hola -f algunarchivo.txt
# Salida
[('-m', 'hola'), ('-f', 'algunarchivo.txt')]
[]
⚠️ La opción abreviada
-m
de este ejemplo no debe confundirse con la bandera de línea de comandos-m
que se utiliza para ejecutar un módulo como módulo principal al ejecutar un script de Python.Por ejemplo, utilizará
python3 -m unittest main.py
para ejecutar unittest como módulo principal al ejecutar main.py.
Hemos mencionado que todos los demás argumentos posicionales que pasemos se recogerán en la variable args
. He aquí un ejemplo:
$ python3 main.py -m hola -f algunarchivo.txt otro_argumento
La lista args
contiene el argumento posicional otro_argumento.
# Salida
[('-m', 'hola'), ('-f', 'algunarchivo.txt')]
['otro_argumento']
Aquí, opts
es una lista de tuplas. Así que podemos hacer un bucle a través de ella, descomprimir la tupla y sacar los argumentos correspondientes a las opciones específicas.
Pero, ¿qué hacemos con el nombre del archivo y el mensaje después de haber procesado estos argumentos? Abriremos el archivo en modo de escritura y escribiremos en él la cadena del mensaje convertida a mayúsculas.
# main.py
import sys
from getopt import getopt
opts, args = getopt(sys.argv[1:],'m:f:',['mensaje=','fichero='])
print(opts)
print(args)
para opción, argumento en opts
si opción == '-m
mensaje = argumento
si opción == '-f':
archivo = argumento
con open(archivo,'w') como f:
f.write(mensaje.superior())
Ejecutemos main.py con las opciones cortas y los argumentos de la línea de comandos.
$ python main.py -m hola -f estearchivo.txt
[('-m', 'hola'), ('-f', 'estearchivo.txt')]
[]
Después de ejecutar main.py, podemos ver ‘estearchivo.txt’ en nuestro directorio de trabajo. Contiene la cadena ‘hola’ convertida a mayúsculas (‘HELLO’).
$ ls
main.py estearchivo.txt
$ cat estefichero.txt
HELLO
Cómo analizar argumentos de la línea de órdenes con argparse
El módulo argparse, también integrado en la biblioteca estándar de Python, proporciona funcionalidad para analizar argumentos de línea de comandos y también construir interfaces de línea de comandos.
Para analizar los argumentos de la línea de comandos, vamos a importar la clase ArgumentParser
del módulo argparse. Aquí, hemos instanciado arg_parser
, un objeto ArgumentParser
:
from argparse import ArgumentParser
arg_parser = ArgumentParser()
A continuación, queremos añadir dos argumentos de línea de comandos
- message: la cadena del mensaje, y
- archivo: el nombre del archivo con el que queremos trabajar.
Ahora llamamos al método add_argument
() en arg_parser
para añadir estos dos argumentos. En la llamada al método add_argument
(), puede establecer la ayuda
en una cadena (una descripción del argumento).
arg_parser.add_argument('mensaje',help='cadena de mensaje')
arg_parser.add_argument('archivo',help='nombre_archivo')
Hasta ahora, hemos instanciado arg_parser
y añadido los argumentos de la línea de comandos. Cuando el programa se ejecuta en la línea de comandos, puede utilizar el método parse_args()
en arg_parser
para obtener los valores de los argumentos.
Aquí, capturamos el espacio de nombres de los argumentos en la variable args
. Así que puede utilizar args .argument_name
para obtener los valores de los argumentos.
Después de obtener los valores de los argumentos, escribimos la cadena del mensaje
con mayúsculas y minúsculas intercambiadas (utilizando el método de cadena swapcase()
) en el archivo
.
args = arg_parser.parse_args()
mensaje = args.mensaje
archivo = args.archivo
con open(archivo,'w') como f:
f.write(mensaje.swapcase())
Poniéndolo todo junto, aquí está nuestro archivo main.py:
# main.py
from argparse import ArgumentParser
arg_parser = ArgumentParser()
arg_parser.add_argument('mensaje',help='cadena del mensaje')
arg_parser.add_argument('archivo',help='nombre de archivo')
args = arg_parser.parse_args()
print(args)
mensaje = args.mensaje
archivo = args.archivo
con open(archivo,'w') como f:
f.write(mensaje.swapcase())
Comprender el uso de los argumentos de la línea de comandos
Para entender el uso de los argumentos al ejecutar main.py, puede utilizar la opción larga --help
como se muestra:
$ python3 main.py --help
uso: main.py [-h] archivo de mensajes
argumentos posicionales:
mensaje mensaje cadena
archivo nombre de archivo
argumentos opcionales:
-h, --help mostrar este mensaje de ayuda y salir
No hay argumentos opcionales y tanto mensaje
como archivo
son argumentos posicionales obligatorios. Alternativamente, también puede utilizar la opción corta -h
:
$ python3 main.py -h
uso: main.py [-h] mensaje archivo
argumentos posicionales:
mensaje mensaje cadena
archivo nombre de archivo
argumentos opcionales:
-h, --help mostrar este mensaje de ayuda y salir
Como se ha visto, ambos argumentos son posicionales por defecto. Así que si no pasa uno o más de estos argumentos, se encontrará con errores.
Aquí, hemos pasado un argumento posicional (Hola) para la cadena de mensaje
, pero no hemos suministrado ningún valor para el argumento archivo
.
Y obtenemos un error que indica que el argumento file
es necesario.
$ python3 main.py Hola
usage: main.py [-h] archivo de mensajes
main.py: error: se requieren los siguientes argumentos: file
Cuando ejecutamos main.py con ambos argumentos posicionales, vemos que el espacio de nombres args
contiene los valores de los argumentos.
$ python3 main.py Hola fichero1.txt
# Salida
Namespace(archivo='archivo1.txt', mensaje='Hola')
Ahora, si examinamos el contenido del directorio de trabajo actual, veremos que el script crea el archivo ‘archivo1.txt’:
$ ls
archivo1.txt main.py
La cadena de mensajes original es ‘Hola’; después de intercambiar las mayúsculas y minúsculas, la cadena de mensajes en el archivo ‘archivo1.txt’ es ‘hELLO’.
$ cat fichero1.txt
hELLO
Cómo hacer que los argumentos de la línea de órdenes sean opcionales
Para hacer que los argumentos de la línea de comandos sean opcionales, puede anteponer --
al nombre del argumento.
Modifiquemos main.py para que tanto el mensaje
como los argumentos de archivo
sean opcionales.
# main.py
from argparse import ArgumentParser
arg_parser = ArgumentParser()
arg_parser.add_argument('--message',help='cadena de mensaje')
arg_parser.add_argument('--file',help='nombre de archivo')
Como los argumentos de la línea de comandos son ambos opcionales, podemos establecer valores por defecto para estos argumentos.
si args.mensaje y args.archivo:
mensaje = args.mensaje
archivo = args.archivo
si no
mensaje = 'Python3
archivo = 'miarchivo.txt'
En este punto, el archivo main.py contiene el siguiente código:
# main.py
from argparse import ArgumentParser
arg_parser = ArgumentParser()
arg_parser.add_argument('--message',help='cadena de mensaje')
arg_parser.add_argument('--file',help='nombre de archivo')
args = arg_parser.parse_args()
print(args)
si args.mensaje y args.archivo:
mensaje = args.mensaje
archivo = args.archivo
si no
mensaje = 'Python3'
archivo = 'miarchivo.txt'
con open(archivo,'w') como f:
f.write(mensaje.swapcase())
Si comprobamos el uso, vemos que tanto mensaje
como fichero son
argumentos opcionales. Lo que significa que ahora puede ejecutar main.py sin estos dos argumentos.
$ python3 main.py --ayuda
usage: main.py [-h] [--mensaje MENSAJE] [--archivo ARCHIVO]
argumentos opcionales:
-h, --help mostrar este mensaje de ayuda y salir
--mensaje MENSAJE cadena de mensajes
--file FILE nombre de archivo
$ python3 principal.py
En el espacio de nombres de los argumentos, tanto archivo
como mensaje
son None
.
# Salida
Espacio de nombres(archivo=Ninguno, mensaje=Ninguno)
Vemos que se utilizan por defecto el nombre de archivo
y el mensaje
‘miarchivo.txt’ y ‘Python3’. El archivo ‘miarchivo.txt’ está ahora en el directorio de trabajo:
$ ls
archivo1.txt main.py miarchivo.txt
Y contiene la cadena ‘Python3’ con las mayúsculas y minúsculas intercambiadas:
$ cat miarchivo.txt
pYTHON3
También puede utilizar los argumentos --message
y --file
para que el comando sea más legible.
$ python3 main.py --mensaje Codificación --archivoarchivo2.txt
# Salida
Namespace(archivo='archivo2.txt', mensaje='Codificación')
Vemos el ‘archivo2.txt’ en el directorio de trabajo:
$ ls
archivo1.txt archivo2.txt main.py miarchivo.txt
Y contiene la cadena ‘cODING’ como se esperaba.
$ cat fichero2.txt
cODING
Conclusión
He aquí un resumen de lo que hemos aprendido en este tutorial:
- Al igual que en el lenguaje de programación C, en Python se puede acceder a los argumentos de la línea de comandos recorriendo el vector de argumentos
sys.argv
.sys.argv[0]
es el nombre del script Python. Así que nos interesa analizar los argumentos sys.argv[1:]
. - Sin embargo, para mejorar la legibilidad y poder añadir opciones, puede utilizar los módulos getopt y argparse.
- Puede utilizar el módulo getopt para analizar la lista de argumentos de la línea de órdenes empezando por el índice 1 hasta el final de la lista. Puede especificar tanto opts cortas como opts largas.
- Cuando una opción toma un argumento, puede especificar dos puntos (:) y = después de la opción corta y la opción larga, respectivamente.
- Con el módulo argparse de Python, puede instanciar un objeto
ArgumentParser
y utilizar el métodoadd_argument()
para añadir un argumento posicional requerido. Utilice--
antes del nombre del argumento para hacerlo opcional. - Para recuperar los valores de los argumentos de la línea de comandos, llame al método
parse_args
() del objetoArgumentParser
.
A continuación, aprenda a realizar hashing seguro en Python.