Pregunta

Estoy usando Argparser para manejar argumentos para mi prog CLI. Pero a medida que pasaba el tiempo creo que no es una buena idea para usarlo. Aquí viene el problema. Quiero usar opciones sin ningún carácter de prefijo. Al igual que git commit o mover SVN . He buscado un poco y encontró que argparse tiene un método add_subparser (). Vamos a poblamos nuestro foo Prog:

parser = argparse.ArgumentParser(prog='foo', usage='%(prog)s [options]')

subparsers = parser.add_subparsers(help='sub-command help')
parser_a = subparsers.add_parser('add', help='a help')
parser_a.add_argument('-ap', '--add-project',
                    nargs='*',
                    action='store',
                    help="Add project")

parser_d = subparsers.add_parser('del', help='a help')
parser_d.add_argument('-dp', '--delete-project',
                    nargs='*',
                    action='store',
                    help="Delete project")

args = parser.parser_args()

Ahora vamos a ejecutar foo con opciones y args espacio de nombres de impresión (que no el pasado todo el código, se consigue el punto):

$ ./foo del
Namespace(delete_project=None)
$ ./foo add
Namespace(add_project=None)

Como se ve, si ejecuto la opción del, add_project no se pasa a la variable args. Que causa problemas si tengo una "cláusula de si" en mi función main () como

def main(args):

   if args.delete_project:
      ...
   if args.add_project:
      ...

Voy a tener una AttributeError excepción, que el espacio de nombre no tiene atributo con el nombre add_project si ejecuto ./foo del. Además de eso, no soy capaz de pasar cualquier argumento a la del opciones y add. También me he fijado prefix_chars a una cadena vacía, que no funcionó bien.

¿Qué es la manera de manejar la situación? Argparse es capaz de crear opciones como Git, SVN, etc .. o debo crear mi propia función y manejar todos los argumentos a mí mismo?

¿Fue útil?

Solución

En lugar de sus instrucciones if, los documentos argparse recomiendan algo como esto :

parser_X.set_defaults(action=action_func)
args.action(args)

A continuación, el add_action mirará add_project y del_action en del_project.

Otros consejos

Editar:. Al parecer, el valor predeterminado para default es None, lo que significa que no tiene uno, por lo que tendrá que usar True y False (que es la forma correcta de todos modos)

Es necesario añadir el default cuando se agrega el argumento para el analizador:

parser_a.add_argument('-ap', '--add-project',
                    nargs = '*',
                    action = 'store_true',
                    default = False,
                    help = "Add project")

Se puede ver la documentación para el método add_argument aquí . (Me doy cuenta de la disposición argparse doc no es el más propicio para encontrar la manera de hacer las cosas que no se llaman a cabo en los ejemplos)

Además, como Tobu señala apropiadamente en su respuesta, los subparsers no utilizados no consigue invocar, por lo que no puede sondear de forma segura sus valores sin al menos proteger su código en un bloque try:. Sin embargo, en realidad se debe utilizar la funcionalidad de la asociación de un action con sus subparsers a menos que tenga una situación mucho más compleja donde necesitan estado de acción.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top