Potrzebuję:
pro [-a xxx | [-b yyy -c zzz]]
Próbowałem tego, ale nie działa. Czy ktoś mógłby mi pomóc?
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")
Dzięki!
Odpowiedzi:
add_mutually_exclusive_group
nie powoduje wykluczenia całej grupy. To sprawia, że opcje w ramach grupy wzajemnie się wykluczają.To, czego szukasz, to podkomendy . Zamiast prog [-a xxxx | [-b yyy -c zzz]], miałbyś:
prog command 1 -a: ... command 2 -b: ... -c: ...
Aby wywołać z pierwszym zestawem argumentów:
Aby wywołać z drugim zestawem argumentów:
Możesz również ustawić argumenty polecenia podrzędnego jako pozycyjne.
Coś jak git lub svn:
Przykład roboczy
# 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')
Sprawdź to
>>> 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
Powodzenia.
źródło
[[-a <val>] | [-b <val1> -c <val2>]]
[-a xxx | [-b yyy -c zzz]]
Chociaż odpowiedź Jonathana jest idealna dla złożonych opcji, istnieje bardzo proste rozwiązanie, które będzie działać w prostych przypadkach, np. 1 opcja wyklucza 2 inne opcje, takie jak w
lub nawet jak w pierwotnym pytaniu:
Oto jak bym to zrobił:
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)
Używam tutaj opcji przekazanych do opakowania wiersza poleceń do odpytywania mongodb.
collection
Instancja może albo wywołać metodęaggregate
lub metodyfind
z opcjonalnych argumentówquery
ifields
stąd widać dlaczego pierwsze dwa argumenty są kompatybilne i ostatni nie jest.Więc teraz biegnę
parser.parse_args()
i sprawdzam zawartość: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)
Oczywiście ten mały hack działa tylko w prostych przypadkach, a sprawdzenie wszystkich możliwych opcji byłoby koszmarem, jeśli masz wiele wzajemnie wykluczających się opcji i grup. W takim przypadku powinieneś przełamać swoje opcje w grupach dowodzenia, jak sugerował Jonathan.
źródło
parser.error("-a and -q ...")
. W ten sposób pełna pomoc dotycząca użytkowania zostanie wydrukowana automatycznie.q
if
są wymagane w pierwszej grupie to użytkownik, (2) każda z grup jest wymagana. I to sprawia, że „proste” rozwiązanie nie jest już takie proste. Zgadzam się więc, że to bardziej hack dla ręcznie wykonanego scenariusza, ale nie jest to prawdziwe rozwiązanieJest łatka Pythona (w fazie rozwoju), która pozwoli ci to zrobić.
http://bugs.python.org/issue10984
Chodzi o to, aby umożliwić nakładanie się wzajemnie wykluczających się grup. Więc
usage
może wyglądać tak:Zmiana kodu argparse, aby można było utworzyć dwie takie grupy, była łatwa. Zmiana
usage
kodu formatowania wymagała napisania niestandardowegoHelpFormatter
.W programie
argparse
grupy akcji nie mają wpływu na analizowanie. Są tylkohelp
narzędziem do formatowania. W grupiehelp
wzajemnie wykluczające się grupy wpływają tylko nausage
linię. Podczas analizowaniaparser
używa wzajemnie wykluczających się grup do tworzenia słownika potencjalnych konfliktów (a
nie może wystąpić zb
lubc
,b
nie może wystąpić za
itp.), A następnie zgłasza błąd w przypadku wystąpienia konfliktu.Myślę, że bez tej argparse patch najlepiej przetestować utworzoną przez
parse_args
siebie przestrzeń nazw (np. Jeśli obiea
ib
mają wartości niedomyślne) i zgłosić swój własny błąd. Możesz nawet użyć własnego mechanizmu błędu parsera.parser.error('custom error message')
źródło