O que eu preciso é:
pro [-a xxx | [-b yyy -c zzz]]
Eu tentei isso, mas não funcionou. Alguém poderia me ajudar?
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")
Obrigado!
Respostas:
add_mutually_exclusive_group
não torna um grupo inteiro mutuamente exclusivo. Isso torna as opções dentro do grupo mutuamente exclusivas.O que você está procurando são subcomandos . Em vez de prog [-a xxxx | [-b yyy -c zzz]], você teria:
prog command 1 -a: ... command 2 -b: ... -c: ...
Para invocar com o primeiro conjunto de argumentos:
Para invocar com o segundo conjunto de argumentos:
Você também pode definir os argumentos do subcomando como posicionais.
Mais ou menos como git ou svn:
Exemplo de Trabalho
# 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')
Teste-o
>>> 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
Boa sorte.
fonte
[[-a <val>] | [-b <val1> -c <val2>]]
[-a xxx | [-b yyy -c zzz]]
Embora a resposta de Jonathan seja perfeitamente adequada para opções complexas, há uma solução muito simples que funcionará para os casos simples, por exemplo, 1 opção exclui 2 outras opções como em
ou mesmo como na pergunta original:
Aqui está como eu faria:
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)
Estou usando aqui as opções fornecidas a um wrapper de linha de comando para consultar um mongodb. A
collection
instância pode chamar o métodoaggregate
ou o métodofind
com argumentos opcionaisquery
efields
, portanto, você vê por que os dois primeiros argumentos são compatíveis e o último não.Então, agora eu corro
parser.parse_args()
e verifico seu conteúdo: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)
Claro, este pequeno hack só funciona para casos simples e seria um pesadelo verificar todas as opções possíveis se você tiver muitas opções e grupos mutuamente exclusivos. Nesse caso, você deve dividir suas opções em grupos de comando como Jonathan sugeriu.
fonte
parser.error("-a and -q ...")
. Desta forma, a ajuda de uso completa será impressa automaticamente.q
ef
são obrigatórios no primeiro grupo é o usuário, (2) qualquer um dos grupos é obrigatório. E isso faz com que a solução "simples" não seja mais tão simples. Então, eu concordaria que este é mais um hack para script artesanal, mas não uma solução realExiste um patch Python (em desenvolvimento) que permite que você faça isso.
http://bugs.python.org/issue10984
A ideia é permitir a sobreposição de grupos mutuamente exclusivos. Então,
usage
pode ser parecido com:Alterar o código argparse para que você possa criar dois grupos como este foi a parte fácil. Alterar o
usage
código de formatação exigiu escrever um código personalizadoHelpFormatter
.Em
argparse
, os grupos de ação não afetam a análise. Eles são apenas umahelp
ferramenta de formatação. Nohelp
, grupos mutuamente exclusivos afetam apenas ausage
linha. Ao analisar, oparser
usa os grupos mutuamente exclusivos para construir um dicionário de conflitos potenciais (a
não pode ocorrer comb
ouc
,b
não pode ocorrer coma
etc.) e, em seguida, gera um erro se surgir um conflito.Sem esse patch argparse, acho que sua melhor escolha é testar o namespace produzido por
parse_args
você (por exemplo, se ambosa
eb
tiverem valores não padrão) e aumentar seu próprio erro. Você pode até usar o mecanismo de erro do próprio analisador.parser.error('custom error message')
fonte