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_groupno 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 xBuena 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
collectioninstancia puede llamar al métodoaggregateo al métodofindcon argumentos opcionalesqueryyfields, 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.qyfson 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
usagepodría verse así:Cambiar el código argparse para poder crear dos grupos como este fue la parte fácil. Cambiar el
usagecódigo de formato requería escribir un archivo personalizadoHelpFormatter.En
argparse, los grupos de acción no afectan el análisis. Son solo unahelpherramienta de formato. En elhelp, los grupos mutuamente excluyentes solo afectan lausagelínea. Al analizar,parserutiliza los grupos mutuamente excluyentes para construir un diccionario de conflictos potenciales (ano puede ocurrir conboc,bno 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_argsusted mismo (por ejemplo, si ambosaybtienen 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