2012-05-22 19 views
30

Mi secuencia de comandos debería iniciar un modo de demostración, cuando no se proporcionan los parámetros. He intentado esto:Argparse: compruebe si se han pasado argumentos

args = parser.parse_args() 
if len(args) == 0: 
    run_demo() 
else: 
    # evaluate args 

que da una *** TypeError: object of type 'Namespace' has no len() como args hay ninguna lista.

¿Cómo puedo lograr lo que quiero?

+0

try de uso, excepto para capturar TypeError, por lo que saben que nada se ha pasado – avasal

+7

@avasal, 'len (args)' siempre arroja una TypeError. – huon

Respuesta

50

Si su objetivo es detectar cuando no se ha dado el argumento al comando, hacerlo a través de argparse es un enfoque incorrecto (como Ben ha señalado muy bien).

¡Piensa simple! :-) Creo que argparse no despobla sys.argv. Entonces, if not len(sys.argv) > 1, el usuario no ha proporcionado ningún argumento.

+0

funciona y es probablemente la mejor/manera más simple de hacerlo: D –

+0

He aceptado esta respuesta, ya que resuelve mi problema, w/o tengo que replantearme las cosas. => bad me;) – Framester

+0

+1 Consejos mucho más prácticos para el problema en cuestión que mi sugerencia de comprobar * todas * las opciones contra 'None'. – Ben

14

argparse le permite establecer (dentro de un objeto de Espacio de nombres) todas las variables mencionadas en los argumentos que ha agregado al analizador, según su especificación y la línea de comando que se está analizando. Si establece un valor predeterminado, esas variables tendrán ese valor predeterminado si no se vieron en la línea de comandos, no estarán ausentes del objeto Espacio de nombres. Y si no se especifica, existe un valor predeterminado implícito de None. Por lo tanto, verificar la longitud del objeto de Espacio de nombres, sin embargo, se las arregla para hacerlo, no tiene sentido como una forma de verificar si se analizaron los argumentos; siempre debe tener la misma longitud.

En cambio, si sabe que tiene muchos argumentos sin valores predeterminados y desea verificar si alguno de ellos se estableció en un valor no None ... haga eso. Puede usar una función de comprensión de listas y vars para recorrerlas sin tener que duplicar la lista de nombres de las llamadas add_argument, como se muestra en la respuesta de Martijn.

Se pone un poco más complicado si algunos de sus argumentos tienen valores predeterminados, y más si tienen valores predeterminados que podrían proporcionarse explícitamente en la línea de comandos (por ejemplo, un argumento numérico predeterminado 0 hace que sea imposible predeterminado del usuario que proporciona 0). En ese caso, no estoy seguro de que haya una solución general que funcione siempre sin conocimiento de cuáles son los argumentos.

+2

Esto explica muy bien por qué tiene un 'problema incorrecto' :) –

+0

+1 para la información – Framester

4

Si uno realmente necesita el número de argumento (por la razón que sea). He encontrado este código muy útil (pero no sé cuánto optimizado es, y agradecería cualquier comentario al respecto).

args = parser.parse_args() 
print(len(vars(args))) 

Esta versión cuenta solo los parámetros -xx y no se transfiere ningún valor adicional.

Si uno quiere todo (también los valores pasados), entonces simplemente use len(sys.argv) como se mencionó anteriormente.

0

que amplió el concepto de 2dvisio para contar los no cero o ninguno Argumentos:

vm_opts = parser.parse_args() 
v = vars(vm_opts) 
n_args = sum([ 1 for a in v.values() if a]) 
1

Supongamos el siguiente ejemplo para extender suyo por completo:

#!/usr/bin/env python3 

import argparse 

... 
def main(): 
    parser = argparse.ArgumentParser() 
    parser.add_argument('input', nargs='?' action='store') 
    parser.add_argument('-l', '--length', type=int, action='store') 
    parser.add_argument('-v', '--verbose', action='store_true') 
    args = parser.parse_args() 
    if (args.input == None and args.length == None): 
     parser.print_help() 
    else: 
     print(args) 

if __name__ == '__main__': 
    main() 

Su objeto Namespace, mencionada por @Ben , en este ejemplo es args. De las cadenas en parser.add_argument se crea una variable.Puede acceder a él a través del args.input o args.length o args.verbose. Esto se puede comprobar mediante la ejecución de print(args) que en realidad va a mostrar algo como esto:

Namespace(input=None, length=None, verbose=False) 

desde verbosa se establece en True, si está presente y la entrada y la longitud son sólo variables, que no tienen que ser instanciado (sin argumentos previsto).

También puede ser útil group = parser.add_mutually_exclusive_group() si desea asegurarse de que no se pueden proporcionar dos atributos simultáneamente.

Para mayor referencia, consulte:

0

No utilice argparse. En su lugar, simplemente use sys.argv. argparse crea un espacio de nombres, por lo que siempre le dará un "dict" con sus valores, dependiendo de los argumentos que utilizó cuando llamó al script.

Esto es lo que he hecho en el pasado:

args = parser.parse_args() 
if len(sys.argv) == 1: 
    parser.print_help() 
    sys.exit() 
return args 
Cuestiones relacionadas