Se busca un ejemplo de argparse simple: 1 argumento, 3 resultados


La documentación para el módulo argparse python, aunque excelente Estoy seguro, es demasiado para que mi pequeño cerebro principiante lo entienda ahora mismo. No necesito hacer matemáticas en la línea de comandos o entrometerme con las líneas de formato en la pantalla o cambiar los caracteres de las opciones. Todo lo que quiero hacer es "Si arg es A, hacer esto, si B hacer eso, si ninguna de las anteriores mostrar ayuda y salir".

Author: Mr. Xcoder, 2011-09-15

9 answers

Mi comprensión de la pregunta original es doble. Primero, en términos del ejemplo de argparse más simple posible, me sorprende que no lo haya visto aquí. Por supuesto, para ser completamente simple, también es todo sobrecarga con poca potencia, pero podría ayudarte a comenzar.

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("a")
args = parser.parse_args()

if args.a == 'magic.name':
    print 'You nailed it!'

Pero este argumento posicional ahora es necesario. Si lo omite al invocar este programa, obtendrá un error sobre los argumentos faltantes. Esto me lleva a la segunda parte de la pregunta original. Matt Wilkie parece querer un único argumento opcional sin una etiqueta con nombre (las etiquetas option option). Mi sugerencia sería modificar el código anterior de la siguiente manera:

...
parser.add_argument("a", nargs='?', default="check_string_for_empty")
...
if args.a == 'check_string_for_empty':
    print 'I can tell that no argument was given and I can deal with that here.'
elif args.a == 'magic.name':
    print 'You nailed it!'
else:
    print args.a

Bien puede haber una solución más elegante, pero esto funciona y es minimalista.

 188
Author: mightypile,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-26 15:31:21

Esta es la forma en que lo hago con argparse (con múltiples argumentos):

parser = argparse.ArgumentParser(description='Description of your program')
parser.add_argument('-f','--foo', help='Description for foo argument', required=True)
parser.add_argument('-b','--bar', help='Description for bar argument', required=True)
args = vars(parser.parse_args())

args será un diccionario que contiene los argumentos:

if args['foo'] == 'Hello':
    # code here

if args['bar'] == 'World':
    # code here

En su caso, simplemente agregue un solo argumento.

 301
Author: Diego Navarro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-12 19:26:03

La documentación de argparse es razonablemente buena, pero deja fuera algunos detalles útiles que podrían no ser obvios. (@Diego Navarro ya mencionó algo de esto, pero trataré de ampliar un poco su respuesta.) El uso básico es el siguiente:

parser = argparse.ArgumentParser()
parser.add_argument('-f', '--my-foo', default='foobar')
parser.add_argument('-b', '--bar-value', default=3.14)
args = parser.parse_args()

El objeto del que se obtiene parse_args() es un objeto 'Namespace': Un objeto cuyas variables miembro reciben el nombre de sus argumentos de línea de comandos. El objeto Namespace es cómo accede a sus argumentos y a los valores asociados con {[14]]}

args = parser.parse_args()
print args.my_foo
print args.bar_value

(Tenga en cuenta que argparse reemplaza '-' en los nombres de los argumentos con guiones bajos al nombrar las variables.)

En muchas situaciones es posible que desee utilizar argumentos simplemente como banderas que no tienen ningún valor. Puedes agregarlos en argparse así:

parser.add_argument('--foo', action='store_true')
parser.add_argument('--no-foo', action='store_false')

Lo anterior creará variables llamadas ' foo ' con valor True, y 'no_foo' con valor False, respectivamente:

if (args.foo):
    print "foo is true"

if (args.no_foo is False):
    print "nofoo is false"

Tenga en cuenta también que puede usar la opción "requerido" al agregar un argumento:

parser.add_argument('-o', '--output', required=True)

De esta manera, si omite este argumento en la línea de comandos argparse le dirá que falta y detendrá la ejecución de su script.

Finalmente, tenga en cuenta que es posible crear una estructura dict de sus argumentos usando la función vars, si eso le facilita la vida.

args = parser.parse_args()
argsdict = vars(args)
print argsdict['my_foo']
print argsdict['bar_value']

Como puede ver, vars devuelve un dict con los nombres de sus argumentos como claves y sus valores como, er, valores.

Hay muchas otras opciones y cosas que puedes hacer, pero esto debería cubrir los escenarios de uso más esenciales y comunes.

 177
Author: DMH,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-13 17:58:08

Matt está preguntando acerca de los parámetros posicionales en argparse, y estoy de acuerdo en que la documentación de Python es deficiente en este aspecto. No hay un solo ejemplo completo en las ~20 páginas impares que muestre analizando y usando parámetros posicionales.

Ninguna de las otras respuestas aquí muestran un ejemplo completo de parámetros posicionales, tampoco, así que aquí hay un ejemplo completo:

# tested with python 2.7.1
import argparse

parser = argparse.ArgumentParser(description="An argparse example")

parser.add_argument('action', help='The action to take (e.g. install, remove, etc.)')
parser.add_argument('foo-bar', help='Hyphens are cumbersome in positional arguments')

args = parser.parse_args()

if args.action == "install":
    print("You asked for installation")
else:
    print("You asked for something other than installation")

# The following do not work:
# print(args.foo-bar)
# print(args.foo_bar)

# But this works:
print(getattr(args, 'foo-bar'))

Lo que me desconcertó es que argparse convertirá el argumento nombrado " fo foo-bar" en "foo_bar", pero un parámetro posicional llamado" foo-bar "permanece como" foo-bar", haciendo menos obvio cómo usarlo en su programa.

Observe las dos líneas cerca del final de mi ejemplo neither ninguna de ellas funcionará para obtener el valor del parámetro posicional foo-bar. El primero es obviamente incorrecto (es una expresión aritmética args.foo minus bar), pero el segundo tampoco funciona:

AttributeError: 'Namespace' object has no attribute 'foo_bar'

Si desea usar el atributo foo-bar, debe usar getattr, como se ve en el último línea de mi ejemplo. Lo que es una locura es que si intentas usar dest=foo_bar para cambiar el nombre de la propiedad a algo que sea más fácil de acceder, obtendrás un mensaje de error realmente extraño:

ValueError: dest supplied twice for positional argument

Así es como se ejecuta el ejemplo anterior:

$ python test.py
usage: test.py [-h] action foo-bar
test.py: error: too few arguments

$ python test.py -h
usage: test.py [-h] action foo-bar

An argparse example

positional arguments:
  action      The action to take (e.g. install, remove, etc.)
  foo-bar     Hyphens are cumbersome in positional arguments

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

$ python test.py install foo
You asked for installation
foo
 49
Author: Mark E. Haase,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-03 17:14:32

Tenga en cuenta el Argparse Tutorialen Python HOWTOs. Comienza con la mayoría de los ejemplos básicos, como este:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
                    help="display a square of a given number")
args = parser.parse_args()
print(args.square**2)

Y progresa a otros menos básicos.

Hay un ejemplo con opción predefinida para una opción, como lo que se pregunta:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
                    help="display a square of a given number")
parser.add_argument("-v", "--verbosity", type=int, choices=[0, 1, 2],
                    help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
if args.verbosity == 2:
    print("the square of {} equals {}".format(args.square, answer))
elif args.verbosity == 1:
    print("{}^2 == {}".format(args.square, answer))
else:
    print(answer)
 9
Author: Alexey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-13 12:27:06

Esto es lo que se me ocurrió en mi proyecto de aprendizaje gracias principalmente a @DMH...

Código de demostración:

import argparse

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-f', '--flag', action='store_true', default=False)  # can 'store_false' for no-xxx flags
    parser.add_argument('-r', '--reqd', required=True)
    parser.add_argument('-o', '--opt', default='fallback')
    parser.add_argument('arg', nargs='*') # use '+' for 1 or more args (instead of 0 or more)
    parsed = parser.parse_args()
    # NOTE: args with '-' have it replaced with '_'
    print('Result:',  vars(parsed))
    print('parsed.reqd:', parsed.reqd)

if __name__ == "__main__":
    main()

Esto puede haber evolucionado y está disponible en línea: command-line.py

Script para darle un entrenamiento a este código: command-line-demo.sh

 6
Author: Peter L,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-18 08:55:38

Otra introducción resumida, inspirada en este post.

import argparse

# define functions, classes, etc.

# executes when your script is called from the command-line
if __name__ == "__main__":

    parser = argparse.ArgumentParser()
    #
    # define each option with: parser.add_argument
    #
    args = parser.parse_args() # automatically looks at sys.argv
    #
    # access results with: args.argumentName
    #

Los argumentos se definen con combinaciones de lo siguiente:

parser.add_argument( 'name', options... )              # positional argument
parser.add_argument( '-x', options... )                # single-char flag
parser.add_argument( '-x', '--long-name', options... ) # flag with long name

Las opciones comunes son:

  • help : descripción de este arg cuando se usa --help.
  • default: valor predeterminado si se omite el arg.
  • escriba : si espera un float o int (de lo contrario es str).
  • dest : dar un nombre diferente a un indicador (por ejemplo, '-x', '--long-name', dest='longName').
    Nota: por defecto --long-name se accede con args.long_name
  • acción: para el manejo especial de ciertos argumentos
    • store_true, store_false: para args booleanos
      '--foo', action='store_true' => args.foo == True
    • store_const: para ser utilizado con opción const
      '--foo', action='store_const', const=42 => args.foo == 42
    • count: para opciones repetidas, como en ./myscript.py -vv
      '-v', action='count' => args.v == 2
    • append: para opciones repetidas, como en ./myscript.py --foo 1 --foo 2
      '--foo', action='append' => args.foo == ['1', '2']
  • required: si un flag es requerido, o un argumento posicional no lo es.
  • nargs : para que una bandera capture N args
    ./myscript.py --foo a b => args.foo = ['a', 'b']
  • choices: para restringir posibles entradas (especifique como lista de cadenas, o ints si type=int).
 5
Author: Sheljohn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-12 14:43:21

Para añadir a lo que otros han declarado:

Normalmente me gusta usar el parámetro 'dest' para especificar un nombre de variable y luego usar 'globals().update () ' para poner esas variables en el espacio de nombres global.

Uso:

$ python script.py -i "Hello, World!"

Código:

...
parser.add_argument('-i', '--input', ..., dest='inputted_variable',...)
globals().update(vars(parser.parse_args()))
...
print(inputted_variable) # Prints "Hello, World!"
 2
Author: Sandy Chapman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-12 13:47:22

También puedes usar plac (una envoltura alrededor de argparse).

Como un bono que genera instrucciones de ayuda aseadas - ver a continuación.

Script de ejemplo:

#!/usr/bin/env python3
def main(
    arg: ('Argument with two possible values', 'positional', None, None, ['A', 'B'])
):
    """General help for application"""
    if arg == 'A':
        print("Argument has value A")
    elif arg == 'B':
        print("Argument has value B")

if __name__ == '__main__':
    import plac
    plac.call(main)

Ejemplo de salida:

No se proporcionaron argumentos - example.py:

usage: example.py [-h] {A,B}
example.py: error: the following arguments are required: arg

Argumento inesperado suministrado - example.py C:

usage: example.py [-h] {A,B}
example.py: error: argument arg: invalid choice: 'C' (choose from 'A', 'B')

Argumento correcto suministrado - example.py A :

Argument has value A

Menú de ayuda completo (generado automáticamente) - example.py -h:

usage: example.py [-h] {A,B}

General help for application

positional arguments:
  {A,B}       Argument with two possible values

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

Breve explicación:

El nombre del argumento generalmente es igual al nombre del parámetro (arg).

La anotación de tupla después del parámetro arg tiene el siguiente significado:

  • Descripción (Argument with two possible values)
  • Tipo de argumento-uno de 'flag', 'option' o 'positional' (positional)
  • Abreviatura (None)
  • Tipo de valor del argumento-eg. flotador, cuerda (None)
  • conjunto Restringido de opciones (['A', 'B'])

Documentación:

Para obtener más información sobre el uso de plac echa un vistazo a su gran documentación:

Lugar: Analizar la Línea de Comandos de la Manera Fácil

 2
Author: quasoft,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-30 17:26:02