2013-05-27 20 views
7

Próbuję mieć wykluczającą się grupę między różnymi grupami: Mam argumenty -a, -b, -c i chcę mieć konflikt z -a i -b razem lub -a i -c razem. Pomoc powinna pokazywać coś takiego jak [-a | ([-pne])].Używanie wzajemnie wykluczających się grup

Poniższy kod nie wydają się mają wzajemnie wykluczające się opcje:

import argparse 
parser = argparse.ArgumentParser(description='My desc') 
main_group = parser.add_mutually_exclusive_group() 
mysub_group = main_group.add_argument_group() 
main_group.add_argument("-a", dest='a', action='store_true', default=False, help='a help') 
mysub_group.add_argument("-b", dest='b', action='store_true',default=False,help='b help') 
mysub_group.add_argument("-c", dest='c', action='store_true',default=False,help='c help') 
parser.parse_args() 

parsowania różne kombinacje - wszystkie pass:

> python myscript.py -h 
usage: myscript.py [-h] [-a] [-b] [-c] 

My desc 

optional arguments: 
    -h, --help show this help message and exit 
    -a   a help 
> python myscript.py -a -c 
> python myscript.py -a -b 
> python myscript.py -b -c 

Próbowałem zmieniając mysub_group być add_mutually_exclusive_group odwraca wszystko do wzajemnie wyłączne:

> python myscript.py -h 
usage: myscript.py [-h] [-a | -b | -c] 

My desc 

optional arguments: 
    -h, --help show this help message and exit 
    -a   a help 
    -b   b help 
    -c   c help 

Jak mogę dodać argumenty dla [-a | ([-pne])]?

Odpowiedz

1

To pytanie zostało zadane wiele razy. Prosta odpowiedź brzmi "z argparse, nie możesz". Jednak to prosta odpowiedź. Można skorzystać z subparsers, więc:

import argparse 
parser = argparse.ArgumentParser(description='My desc') 
sub_parsers = parser.add_subparsers() 
parser_a = sub_parsers.add_parser("a", help='a help') 
parser_b = sub_parsers.add_parser("b", help='b help') 
parser_b.add_argument("-c", dest='c', action='store_true',default=False,help='c help') 
parser.parse_args() 

Następnie otrzymujemy:

$ python parser -h 
usage: parser [-h] {a,b} ... 

My desc 

positional arguments: 
    {a,b} 
    a   a help 
    b   b help 

optional arguments: 
    -h, --help show this help message and exit 

oraz:

$ python parser b -h 
usage: parser b [-h] [-c] 

optional arguments: 
    -h, --help show this help message and exit 
    -c   c help 

Jeśli wolisz swoje argumenty jak wskazano w pytaniu, mają spójrz na docopt, wygląda pięknie i powinien zrobić dokładnie to, co chcesz.

+0

Nie bardzo tego chcę, ponieważ nie daje mi opcji po prostu -c (bez opcji -b). – itzhaki

+0

To prawda, moje przeprosiny. Nie sądzę, że można uzyskać dokładnie to, co chcesz z argparse, ale nadal uważam, że docopt jest dobrym wyborem, wystarczy dodać użycie: myscript.py [-h | -a | [-b -c]] do twojego docstringu i wszystko będzie dla ciebie działało –

0

argument_groups nie mają wpływu na parsowanie. Przyczyniają się tylko do formatowania pomocy. Zatem zdefiniowanie grupy w ramach mutually_exclusive_group nie pomaga w tym problemie.

Jest proponowana poprawka, http://bugs.python.org/issue10984, 'argparse add_mutually_exclusive_group should accept existing arguments to register conflicts', które pozwalają na zdefiniowanie dwóch mutually_exclusive_groups, jeden [-a | -b] i inne [-a | -c]. Tworzenie drugiej grupy zawierającej argument (-a), który jest już zdefiniowany, jest banalną częścią tej poprawki. Wytworzenie sensownej linii użycia jest trudniejsze i wymaga przepisania kilku metod.

import argparse 
parser = argparse.ArgumentParser(description='My desc') 
group1 = parser.add_mutually_exclusive_group() 
action_a = group1.add_argument("-a", dest='a', action='store_true', default=False, help='a help') 
group1.add_argument("-b", dest='b', action='store_true',default=False,help='b help') 

group2 = parser.add_mutually_exclusive_group() 
group2.add_argument("-c", dest='c', action='store_true',default=False,help='c help') 
group2._group_actions.append(action_a) # THE KLUDGE 

print parser.format_usage() 
# usage: stack16769409.py [-h] [-a | -b] [-c] 

args = parser.parse_args() 

Usage nie pokazuje poprawnie 2 grup. Ale akceptuje ona -b -c, jednocześnie sprzeciwiając się -a -b i -a -c. Ale możesz napisać niestandardową linię użycia.

Powiązane problemy