Lo que necesito es:
pro [-a xxx | [-b yyy -c zzz]]
Intenté esto pero no funciona. podria alguien ayudarme?
group= parser.add_argument_group('Model 2')
group_ex = group.add_mutually_exclusive_group()
group_ex.add_argument("-a", type=str, action = "store", default = "", help="test")
group_ex_2 = group_ex.add_argument_group("option 2")
group_ex_2.add_argument("-b", type=str, action = "store", default = "", help="test")
group_ex_2.add_argument("-c", type=str, action = "store", default = "", help="test")
¡Gracias!
Respuestas:
add_mutually_exclusive_group
no hace que todo un grupo se excluya mutuamente. Hace que las opciones dentro del grupo sean mutuamente excluyentes.Lo que está buscando son subcomandos . En lugar de prog [-a xxxx | [-b yyy -c zzz]], tendrías:
prog command 1 -a: ... command 2 -b: ... -c: ...
Para invocar con el primer conjunto de argumentos:
Para invocar con el segundo conjunto de argumentos:
También puede establecer los argumentos del subcomando como posicionales.
Algo así como git o svn:
Ejemplo de trabajo
# create the top-level parser parser = argparse.ArgumentParser(prog='PROG') parser.add_argument('--foo', action='store_true', help='help for foo arg.') subparsers = parser.add_subparsers(help='help for subcommand') # create the parser for the "command_1" command parser_a = subparsers.add_parser('command_1', help='command_1 help') parser_a.add_argument('a', type=str, help='help for bar, positional') # create the parser for the "command_2" command parser_b = subparsers.add_parser('command_2', help='help for command_2') parser_b.add_argument('-b', type=str, help='help for b') parser_b.add_argument('-c', type=str, action='store', default='', help='test')
Pruébalo
>>> parser.print_help() usage: PROG [-h] [--foo] {command_1,command_2} ... positional arguments: {command_1,command_2} help for subcommand command_1 command_1 help command_2 help for command_2 optional arguments: -h, --help show this help message and exit --foo help for foo arg. >>> >>> parser.parse_args(['command_1', 'working']) Namespace(a='working', foo=False) >>> parser.parse_args(['command_1', 'wellness', '-b x']) usage: PROG [-h] [--foo] {command_1,command_2} ... PROG: error: unrecognized arguments: -b x
Buena suerte.
fuente
[[-a <val>] | [-b <val1> -c <val2>]]
[-a xxx | [-b yyy -c zzz]]
Si bien la respuesta de Jonathan está perfectamente bien para opciones complejas, existe una solución muy simple que funcionará para los casos simples, por ejemplo, 1 opción excluye otras 2 opciones como en
o incluso como en la pregunta original:
Así es como lo haría:
parser = argparse.ArgumentParser() # group 1 parser.add_argument("-q", "--query", help="query", required=False) parser.add_argument("-f", "--fields", help="field names", required=False) # group 2 parser.add_argument("-a", "--aggregation", help="aggregation", required=False)
Estoy usando aquí las opciones dadas a un contenedor de línea de comando para consultar un mongodb. La
collection
instancia puede llamar al métodoaggregate
o al métodofind
con argumentos opcionalesquery
yfields
, por lo tanto, puede ver por qué los dos primeros argumentos son compatibles y el último no.Así que ahora corro
parser.parse_args()
y verifico su contenido:args = parser().parse_args() print args.aggregation if args.aggregation and (args.query or args.fields): print "-a and -q|-f are mutually exclusive ..." sys.exit(2)
Por supuesto, este pequeño truco solo funciona para casos simples y sería una pesadilla verificar todas las opciones posibles si tiene muchas opciones y grupos mutuamente excluyentes. En ese caso, debe dividir sus opciones en grupos de comando como sugirió Jonathan.
fuente
parser.error("-a and -q ...")
. De esta forma, la ayuda de uso completa se imprimirá automáticamente.q
yf
son obligatorios en el primer grupo es el usuario, (2) se requiere cualquiera de los grupos. Y esto hace que la solución "simple" ya no sea tan simple. Así que estaría de acuerdo en que esto es más un truco para un guión hecho a mano, pero no una solución realHay un parche de Python (en desarrollo) que le permitiría hacer esto.
http://bugs.python.org/issue10984
La idea es permitir la superposición de grupos mutuamente excluyentes. Entonces
usage
podría verse así:Cambiar el código argparse para poder crear dos grupos como este fue la parte fácil. Cambiar el
usage
código de formato requería escribir un archivo personalizadoHelpFormatter
.En
argparse
, los grupos de acción no afectan el análisis. Son solo unahelp
herramienta de formato. En elhelp
, los grupos mutuamente excluyentes solo afectan lausage
línea. Al analizar,parser
utiliza los grupos mutuamente excluyentes para construir un diccionario de conflictos potenciales (a
no puede ocurrir conb
oc
,b
no puede ocurrir cona
, etc.), y luego genera un error si surge un conflicto.Sin ese parche de argparse, creo que su mejor opción es probar el espacio de nombres producido por
parse_args
usted mismo (por ejemplo, si ambosa
yb
tienen valores no predeterminados) y generar su propio error. Incluso podría utilizar el propio mecanismo de error del analizador.parser.error('custom error message')
fuente