¿Cómo leer / procesar argumentos de línea de comando?

Soy originalmente un progtwigdor de C He visto numerosos trucos y “hacks” para leer muchos argumentos diferentes.

¿Cuáles son algunas de las formas en que los progtwigdores de Python pueden hacer esto?

Relacionado

  • ¿Cuál es la mejor manera de capturar / analizar los argumentos de la línea de comandos pasados ​​a un script de Python?
  • ¿Implementando interfaces de línea de comandos de estilo “[comando] [acción] [parámetro]”?
  • ¿Cómo puedo procesar los argumentos de la línea de comandos en Python?
  • ¿Cómo formateo la ayuda de los argumentos posicionales usando el optparse de Python?

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

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() 

Soporta argparse (entre otras cosas):

  • Múltiples opciones en cualquier orden.
  • Opciones cortas y largas.
  • Valores predeterminados.
  • Generación de un mensaje de ayuda de uso.
 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 comandos.

Básicamente,

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

Simplemente ir a evangelizar por argparse, lo cual es mejor por estas razones … esencialmente:

(Copiado desde el enlace)

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

  • argparse no es dogmático acerca de cómo debe verse la interfaz de la línea de comandos; se admiten opciones como -file o / file, al igual que las opciones requeridas. Optparse se niega a admitir estas características, prefiriendo la pureza por encima de lo práctico

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

  • argparse admite acciones que consumen un número variable de argumentos de línea de comando, mientras que optparse requiere que el número exacto de argumentos (por ejemplo, 1, 2 o 3) sea conocido de antemano

  • argparse admite analizadores que se envían a subcomandos, mientras que optparse requiere configurar allow_interspersed_args y hacer el envío del analizador manualmente

Y mi favorito personal:

  • argparse permite que los parámetros de tipo y acción para add_argument() se especifiquen con callables simples, mientras que optparse requiere atributos de clase de pirateo como STORE_ACTIONS o CHECK_METHODS para obtener la verificación correcta de los argumentos.

También hay argparse módulo argparse stdlib (una “mejora” en el módulo optparse de optparse ). 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 

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 

La biblioteca docopt es realmente elegante. Construye un argumento dict a partir de la cadena de uso de tu aplicación.

Por ejemplo, desde el docopt readme:

 """Naval Fate. Usage: naval_fate.py ship new ... naval_fate.py ship  move   [--speed=] naval_fate.py ship shoot   naval_fate.py mine (set|remove)   [--moored | --drifting] naval_fate.py (-h | --help) naval_fate.py --version Options: -h --help Show this screen. --version Show version. --speed= 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) 

Si necesitas algo rápido y no muy flexible.

main.py:

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

Luego ejecuta python main.py James Smith

para producir el siguiente resultado:

Hola james smith

 #set default args as -h , if no args: if len(sys.argv) == 1: sys.argv[1:] = ["-h"] 

Yo uso optparse, pero me gusta mucho la dirección que está tomando Simon Willison con su biblioteca optfunc recientemente introducida. Funciona por:

“inspeccionar una definición de función (incluidos sus argumentos y sus valores predeterminados) y usarla para construir un analizador de argumento de línea de comandos”.

Entonces, por ejemplo, esta definición de función:

 def geocode(s, api_key='', geocoder='google', list_geocoders=False): 

se convierte en este texto de ayuda optparse:

  Options: -h, --help show this help message and exit -l, --list-geocoders -a API_KEY, --api-key=API_KEY -g GEOCODER, --geocoder=GEOCODER 

Me gusta getopt de stdlib, por ejemplo:

 try: opts, args = getopt.getopt(sys.argv[1:], 'h', ['help']) except getopt.GetoptError, err: usage(err) for opt, arg in opts: if opt in ('-h', '--help'): usage() if len(args) != 1: usage("specify thing...") 

Últimamente, he estado envolviendo algo similar a esto para hacer las cosas menos detalladas (por ejemplo, haciendo “-h” implícito).

Como puede ver optparse “El módulo optparse está en desuso y no se desarrollará más; el desarrollo continuará con el módulo argparse “.

El clic de Pocoo es más intuitivo, requiere menos repetición y es al menos tan poderoso como argparse.

La única debilidad que he encontrado hasta ahora es que no puede hacer mucha personalización para ayudar a las páginas, pero eso generalmente no es un requisito y docopt parece ser la opción clara cuando lo es.

Es posible que le interese un pequeño módulo de Python que escribí para facilitar el manejo de los argumentos de la línea de comandos (código abierto y de uso gratuito) – Comando

Recomiendo ver docopt como una alternativa simple a estos otros.

docopt es un nuevo proyecto que funciona al analizar su mensaje de uso de ayuda en lugar de requerirle que implemente todo. Solo tienes que poner tu mensaje de uso en el formato POSIX.

Otra opción es argh . Se basa en argparse y te permite escribir cosas como:

 import argh # declaring: def echo(text): "Returns given word as is." return text def greet(name, greeting='Hello'): "Greets the user with given name. The greeting is customizable." return greeting + ', ' + name # assembling: parser = argh.ArghParser() parser.add_commands([echo, greet]) # dispatching: if __name__ == '__main__': parser.dispatch() 

Se generará automáticamente ayuda y así sucesivamente, y puede usar decoradores para proporcionar orientación adicional sobre cómo debería funcionar el análisis de argumentos.

 import argparse parser = argparse.ArgumentParser(description='Process some integers.') parser.add_argument('integers', metavar='N', type=int, nargs='+', help='an integer for the accumulator') 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)) Assuming the Python code above is saved into a file called prog.py $ python prog.py -h Ref-link: https://docs.python.org/3.3/library/argparse.html 

Mi solución es entrypoint2 . Ejemplo:

 from entrypoint2 import entrypoint @entrypoint def add(file, quiet=True): ''' This function writes report. :param file: write report to FILE :param quiet: don't print status messages to stdout ''' print file,quiet 

texto de ayuda:

 usage: report.py [-h] [-q] [--debug] file This function writes report. positional arguments: file write report to FILE optional arguments: -h, --help show this help message and exit -q, --quiet don't print status messages to stdout --debug set logging level to DEBUG