¿Cómo puedo leer y procesar (analizar) los argumentos de la línea de comandos?

8 minutos de lectura

En Python, ¿cómo podemos averiguar los argumentos de la línea de comandos que se proporcionaron para un script y procesarlos?


Lectura de fondo relacionada: ¿Qué significa “sys.argv[1]” significa? (¿Qué es sys.argv y de dónde proviene?). Para obtener algunos ejemplos más específicos, consulte Implementación de un “[command] [action] [parameter]” diseñar interfaces de línea de comandos? y ¿Cómo formateo la ayuda de argumentos posicionales usando optparse de Python?.

  • Use docopt (vea la respuesta de @ralbatross en stackoverflow.com/a/14790373/116891). Lo he intentado de todas las formas y, realmente, docopt es el único que usaré en el futuro.

    – Pat

    21 de octubre de 2013 a las 2:50

  • No creo que haya una sola mejor manera. argparse es estándar y con muchas funciones. docopt es muy elegante pero no está en la biblioteca estándar. Para un uso muy fácil y liviano, puede hacer que los valores predeterminados de la función manejen los valores predeterminados de los argumentos de la línea de comandos por usted.

    – Simón Hibbs

    5 de abril de 2017 a las 15:27

Avatar de usuario de John Slavick
Juan Slavick

import sys

print("\n".join(sys.argv))

sys.argv es una lista que contiene todos los argumentos pasados ​​al script en la línea de comando. sys.argv[0] es el nombre del guión.

Básicamente,

import sys
print(sys.argv[1:])

  • Para cosas realmente simples, este es el camino a seguir, aunque probablemente solo quieras usar sys.argv[1:] (evita el nombre del script).

    – Xiong Chiamiov

    12 de septiembre de 2010 a las 7:31


Avatar de usuario de Ayman Hourieh
Ayman Hourieh

La solución canónica en la biblioteca estándar es argparse (documentos):

Aquí hay un ejemplo:

from argparse import ArgumentParser

parser = ArgumentParser()
parser.add_argument("-f", "--file", dest="filename",
                    help="write report to FILE", metavar="FILE")
parser.add_argument("-q", "--quiet",
                    action="store_false", dest="verbose", default=True,
                    help="don't print status messages to stdout")

args = parser.parse_args()

argparse apoya (entre otras cosas):

  • Múltiples opciones en cualquier orden.
  • Opciones cortas y largas.
  • Valores predeterminados.
  • Generación de un mensaje de ayuda al uso.

  • Sí, estos son los mejores. Dado que forman parte de la biblioteca estándar, puede estar seguro de que estarán disponibles y de que son fáciles de usar. optparse en particular es poderoso y fácil.

    –Barry Wark

    17 de junio de 2009 a las 22:43

  • optparse es uno de los mejores; getopt es antiguo y realmente debería considerarse obsoleto.

    – jemfinch

    9 de abril de 2010 a las 20:49

  • en este punto (12/2011), argparse ahora se considera una mejor opción que optparse, ¿correcto?

    – oob

    20 de diciembre de 2011 a las 21:48

  • La documentación de Python sugiere el uso de análisis de argumentos en lugar de optparse.

    – sandía

    22 mayo 2012 a las 15:45

  • Desde optparse está en desuso, el autor de la pregunta ya no es miembro del desbordamiento de pila, y esta es la respuesta aceptada en una pregunta muy visible; considere reescribir completamente su código de ejemplo para usar stdlib argparse en cambio.

    – Wim

    23 de mayo de 2018 a las 17:13


Simplemente dando vueltas evangelizando para análisis de argumentos que es mejor para estos razones… esencialmente:

(copiado del enlace)

  • El módulo argparse puede manejar argumentos posicionales y opcionales, mientras que optparse solo puede manejar argumentos opcionales.

  • argparse no es dogmático sobre el aspecto que debe tener su interfaz de línea de comandos: se admiten opciones como -file o /file, al igual que las opciones requeridas. Optparse se niega a admitir estas funciones y prefiere la pureza a la practicidad.

  • argparse produce mensajes de uso más informativos, incluido el uso de la línea de comandos determinado a partir de sus argumentos, y mensajes de ayuda para argumentos posicionales y opcionales. El módulo optparse requiere que escriba su propia cadena de uso y no tiene forma de mostrar ayuda para argumentos posicionales.

  • argparse admite acciones que consumen una cantidad variable de argumentos de línea de comandos, mientras que optparse requiere que se conozca de antemano la cantidad exacta de argumentos (p. ej., 1, 2 o 3).

  • argparse admite analizadores que se envían a subcomandos, mientras que optparse requiere configuración
    allow_interspersed_args y haciendo el envío del analizador manualmente

Y mi favorito personal:

  • argparse permite que los parámetros de tipo y acción add_argument()
    para especificarse con invocables simples, mientras que optparse requiere atributos de clase de piratería como
    STORE_ACTIONS o CHECK_METHODS para obtener la verificación de argumento adecuada

  • Esto ahora es parte de Python estándar a partir de 2.7 y 3.2 🙂

    – jpswain

    3 de septiembre de 2010 a las 2:08

  • ¿Qué son los “argumentos opcionales”? Dices que están en optparse. Pensé que eran argumentos que pueden proporcionarse o no, pero usted dijo que están en optparse mientras decía que “optparse requiere que se conozca de antemano la cantidad exacta de argumentos”. Entonces, su definición de “argumento opcional” difiere de lo que pensé, o su respuesta es inconsistente consigo misma.

    – El arte de la guerra

    7 de agosto de 2014 a las 12:44

  • Solo una queja: la documentación de argparse también es increíblemente complicada. No puede obtener una respuesta simple para “¿cómo hago para que un argumento de la línea de comando tome un solo valor y cómo accedo a ese valor?”

    – osmán

    13 de abril de 2017 a las 19:09

  • @osman Este gentil tutorial en argparse podría ayudar …

    – Balance de vida

    13 de junio de 2017 a las 15:51

  • @ArtOfWarfare “argumentos opcionales” en este contexto presumiblemente significa argumentos especificados con argumentos de tipo opción como -f o --foomientras que “el número exacto de argumentos se conoce de antemano” presumiblemente significa argumentos posicionales dados sin ningún indicador de opción anterior.

    – mtraceur

    25 de julio de 2018 a las 23:55

avatar de usuario de jfs
jfs

También hay argparse módulo stdlib (una “mejora” en stdlib’s optparse módulo). Ejemplo de la introducción a argparse:

# script.py
import argparse

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument(
        'integers', metavar="int", type=int, choices=range(10),
         nargs="+", help='an integer in the range 0..9')
    parser.add_argument(
        '--sum', dest="accumulate", action='store_const', const=sum,
        default=max, help='sum the integers (default: find the max)')

    args = parser.parse_args()
    print(args.accumulate(args.integers))

Uso:

$ script.py 1 2 3 4
4

$ script.py --sum 1 2 3 4
10

Avatar de usuario de Kent Munthe Caspersen
Kent Munthe Caspersen

Si necesitas algo rápido y poco flexible

principal.py:

import sys

first_name = sys.argv[1]
last_name = sys.argv[2]
print("Hello " + first_name + " " + last_name)

Entonces corre python main.py James Smith

para producir la siguiente salida:

Hola James Smith

  • Un uso más realista sería python main.py "James Smith" que pone James Smith en sys.argv[1] y produce un IndexError cuando intentas usar lo inexistente sys.argv[2]. El comportamiento de las citas dependerá en cierta medida de la plataforma y el shell desde el que ejecute Python.

    – triplete

    22 de diciembre de 2017 a las 8:02


  • No estoy de acuerdo en que mi uso sea menos realista. Suponga que su programa necesita saber el nombre y apellido exactos de una persona para ejecutar el script en un negocio donde las personas pueden tener varios nombres y apellidos. Si James Smith tiene a Joseph como nombre o apellido adicional, ¿cómo distinguiría si Joseph es un nombre o apellido adicional si solo lo hace? python main.py "James Joseph Smith"? Si le preocupa el índice fuera de los límites, puede agregar una verificación para la cantidad de argumentos proporcionados. Menos realista o no, mi ejemplo muestra cómo manejar múltiples argumentos.

    – Kent Munthe Caspersen

    01/01/2018 a las 19:55

  • Todas las demás respuestas son para trazar una misión de aterrizaje lunar. Simplemente estoy usando gmail-trash-msg.py MessageID. Esta respuesta es sencilla de probar. MessageID el parámetro ha sido pasado en sys.argv[1].

    – WinEunuuchs2Unix

    22 mayo 2019 a las 23:27

avatar de usuario de ralbatross
ralbatross

El docoptar la biblioteca es realmente elegante. Crea un dictado de argumento a partir de la cadena de uso para su aplicación.

Por ejemplo, desde el archivo Léame de docopt:

"""Naval Fate.

Usage:
  naval_fate.py ship new <name>...
  naval_fate.py ship <name> move <x> <y> [--speed=<kn>]
  naval_fate.py ship shoot <x> <y>
  naval_fate.py mine (set|remove) <x> <y> [--moored | --drifting]
  naval_fate.py (-h | --help)
  naval_fate.py --version

Options:
  -h --help     Show this screen.
  --version     Show version.
  --speed=<kn>  Speed in knots [default: 10].
  --moored      Moored (anchored) mine.
  --drifting    Drifting mine.

"""
from docopt import docopt


if __name__ == '__main__':
    arguments = docopt(__doc__, version='Naval Fate 2.0')
    print(arguments)

  • Un uso más realista sería python main.py "James Smith" que pone James Smith en sys.argv[1] y produce un IndexError cuando intentas usar lo inexistente sys.argv[2]. El comportamiento de las citas dependerá en cierta medida de la plataforma y el shell desde el que ejecute Python.

    – triplete

    22 de diciembre de 2017 a las 8:02


  • No estoy de acuerdo en que mi uso sea menos realista. Suponga que su programa necesita saber el nombre y apellido exactos de una persona para ejecutar el script en un negocio donde las personas pueden tener varios nombres y apellidos. Si James Smith tiene a Joseph como nombre o apellido adicional, ¿cómo distinguiría si Joseph es un nombre o apellido adicional si solo lo hace? python main.py "James Joseph Smith"? Si le preocupa el índice fuera de los límites, puede agregar una verificación para la cantidad de argumentos proporcionados. Menos realista o no, mi ejemplo muestra cómo manejar múltiples argumentos.

    – Kent Munthe Caspersen

    01/01/2018 a las 19:55

  • Todas las demás respuestas son para trazar una misión de aterrizaje lunar. Simplemente estoy usando gmail-trash-msg.py MessageID. Esta respuesta es sencilla de probar. MessageID el parámetro ha sido pasado en sys.argv[1].

    – WinEunuuchs2Unix

    22 mayo 2019 a las 23:27

Avatar de usuario de Peter Mortensen
Pedro Mortensen

Una forma de hacerlo es usando sys.argv. Esto imprimirá el nombre del script como el primer argumento y todos los demás parámetros que le pases.

import sys

for arg in sys.argv:
    print arg

¿Ha sido útil esta solución?