python - example - Ejemplo de argparse simple quería: 1 argumento, 3 resultados
python argparse argumentparser() (9)
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.
La documentation para el módulo de python argparse , aunque excelente, estoy segura, es demasiado para mi pequeño cerebro de principiante ahora mismo. No necesito hacer cálculos matemáticos en la línea de comandos o entrometerme con las líneas de formato en la pantalla o cambiar los caracteres de opción. Todo lo que quiero hacer es "Si arg es A, haz esto, si B hace eso, si ninguno de los anteriores muestra ayuda y abandona" .
Esto es lo que se me ocurrió en mi proyecto de aprendizaje gracias principalmente a @DMH ...
Código demo:
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 a este código un entrenamiento: command-line-demo.sh
La documentación argparse
es razonablemente buena pero argparse
algunos detalles útiles que pueden no ser obvios. (@Diego Navarro ya mencionó algo de esto, pero intentaré ampliar su respuesta ligeramente). 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 que recuperas de parse_args()
es un objeto ''Espacio de nombres'': un objeto cuyas variables miembro reciben su nombre de tus argumentos de línea de comando. El objeto de Namespace
es cómo accede a sus argumentos y los valores asociados con ellos:
args = parser.parse_args()
print args.my_foo
print args.bar_value
(Tenga en cuenta que argparse
reemplaza ''-'' en los nombres de sus argumentos con guiones bajos al nombrar las variables).
En muchas situaciones, es posible que desee utilizar argumentos simplemente como indicadores 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 esa manera, si omite este argumento en la línea de comandos, argparse
le dirá que falta y detiene la ejecución de su script.
Finalmente, tenga en cuenta que es posible crear una estructura de dict de sus argumentos utilizando 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 puede hacer, pero esto debería cubrir los escenarios de uso más comunes y esenciales.
Matt está preguntando sobre los parámetros posicionales en argparse, y estoy de acuerdo en que la documentación de Python no se encuentra en este aspecto. No hay un solo ejemplo completo en las ~ 20 páginas impares que muestra tanto el análisis como el uso de parámetros posicionales .
Ninguna de las otras respuestas aquí muestra un ejemplo completo de parámetros posicionales, 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 echó fuera es que argparse convertirá el argumento llamado "--foo-bar" en "foo_bar", pero un parámetro posicional llamado "foo-bar" permanece como "foo-bar", haciendo que sea menos obvio cómo Úsalo en tu programa.
Observe las dos líneas cerca del final de mi ejemplo: 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 menos barra), 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 la última 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ías un mensaje de error realmente extraño:
ValueError: dest supplied twice for positional argument
Así es como funciona 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
Mi comprensión de la pregunta original es doble. Primero, en términos del ejemplo 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 poco poder, pero podrí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 requerido. Si lo deja al invocar este programa, obtendrá un error sobre los argumentos que faltan. Esto me lleva a la segunda parte de la pregunta original. Matt Wilkie parece querer un solo argumento opcional sin una etiqueta con nombre (las etiquetas --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.
Otra introducción sumaria, 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 para este argumento cuando se usa
--help
. - default : valor predeterminado si se omite el argumento.
- type : si espera un
float
oint
(de lo contrario esstr
). - dest : dest un nombre diferente a una bandera (por ejemplo,
''-x'', ''--long-name'', dest=''longName''
).
Nota: por defecto--long-name
se accede al--long-name
args.long_name
conargs.long_name
- action : para el manejo especial de ciertos argumentos.
-
store_true, store_false
: parastore_true, store_false
booleanos
''--foo'', action=''store_true'' => args.foo == True
-
store_const
: para ser usado con la opciónconst
''--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 se requiere una bandera, o un argumento posicional no lo es.
- nargs : por una bandera para capturar n args
./myscript.py --foo ab => args.foo = [''a'', ''b'']
- choices : para restringir las entradas posibles (especifique como lista de cadenas, o ints si
type=int
).
Para agregar a lo que otros han dicho:
Por lo general, me gusta usar el parámetro ''dest'' para especificar un nombre de variable y luego usar ''globals (). Update ()'' para colocar 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!"
También puedes usar plac (un envoltorio alrededor de argparse
).
Como beneficio adicional, genera instrucciones de ayuda ordenadas - vea más abajo.
Ejemplo de script:
#!/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 hay argumentos proporcionados - 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 ''bandera'', ''opción'' o ''posicional'' (
positional
) - Abreviatura (
None
) - Tipo de valor de argumento - por ejemplo. flotar, cadena (
None
) - Conjunto restringido de opciones (
[''A'', ''B'']
)
Documentación:
Para obtener más información sobre el uso de plac consulte su excelente documentación:
Tenga en cuenta el tutorial de Argparse en los CÓMO de Python . 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 avanza hacia los menos básicos.
Hay un ejemplo con una 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)