2011-11-23 10 views
107

Creo que esto debe ser fácil pero no lo entiendo.argparse: identificar qué subparser se utilizó

Supongamos que tengo el siguiente analizador arparse:

import argparse 

parser = argparse.ArgumentParser(version='pyargparsetest 1.0') 
subparsers = parser.add_subparsers(help='commands') 

# all 
all_parser = subparsers.add_parser('all', help='process all apps') 

# app 
app_parser = subparsers.add_parser('app', help='process a single app') 
app_parser.add_argument('appname', action='store', help='name of app to process') 

¿Cómo puedo identificar, que subparser se utilizó? vocación:

print parser.parse_args(["all"]) 

me da un espacio de nombres vacío:

Namespace() 
+0

Esta pregunta en mi humilde opinión tiene mejor respuesta, entonces la considerada originales. –

Respuesta

56

Editar: favor ver quornian's answer a esta pregunta, que es mejor que la mía y debe ser la respuesta aceptada.

De acuerdo con argparse documentation el resultado de parser.parse_args(...) "solo contendrá atributos para el analizador principal y el analizador secundario que se seleccionó". Desafortunadamente, esta información puede no ser suficiente para determinar qué sub-analizador se utilizó. La documentación recomienda utilizar el método set_defaults(...) en el analizador secundario para resolver este problema.

Por ejemplo, he añadido las llamadas a set_defaults() a su código:

import argparse 

parser = argparse.ArgumentParser(version='pyargparsetest 1.0') 
subparsers = parser.add_subparsers(help='commands') 

# all 
all_parser = subparsers.add_parser('all', help='process all apps') 
all_parser.set_defaults(which='all') 

# app 
app_parser = subparsers.add_parser('app', help='process a single app') 
app_parser.add_argument('appname', action='store', help='name of app to process') 
app_parser.set_defaults(which='app') 

Ahora si ejecuta

print parser.parse_args(["all"]) 

El resultado es

Namespace(which='all') 

Mira la add_subparsers() documentación para más información y otro ejemplo.

+5

'set_defaults' es útil, como en el ejemplo de los documentos donde lo usa para vincular un subcomando a una función ... pero' add_parser (dest = 'which') 'parece ser la forma" correcta "de hacer esto , ya que no es necesario repetir el nombre del subcomando – dbr

+1

@dbr Yep, tienes razón. La respuesta de Quornian debería ser la aceptada. – srgerg

+0

@dbr, debe ser 'add_subparsers (dest = 'which')' – smac89

202

Una solución más simple es agregar dest a la llamada add_subparsers. Esto está enterrado un poco más abajo en el documentation:

[...] Si es necesario comprobar el nombre de la subparser que fue invocado, la palabra clave dest argumento para los add_subparsers() llamada funcionará

En su ejemplo reemplazar:

subparsers = parser.add_subparsers(help='commands') 

con:

subparsers = parser.add_subparsers(help='commands', dest='command') 

Ahora si ejecuta:

print parser.parse_args(["all"]) 

obtendrá

Namespace(command='all') 
+0

Esto parece ser la forma correcta, ya que funciona como el parámetro 'dest' en cualquier otro argumento (solo se usa' None', en lugar de ser retirado del valor '--longopt'). Usar 'set_defaults' parece inadecuado para esto (pero útil para otras cosas) – dbr

+0

¡Esta es la respuesta correcta! Sería bueno tener un ejemplo de cómo probar el valor de "comando". –

+0

BTW si hay una función en la misma clase por el nombre del comando que uno podría hacer: "getattr (self, args.command)()" para ejecutarlo por su nombre! –

Cuestiones relacionadas