2014-07-08 10 views
5

Próbuję realizować następujące:jak add_argument_group do add_mutually_exclusive_group z pytona argparse

$ prog.py -h 
usage: prog.py [-h] [-s | -m] [[-y [year]] | [[-1 | -3] [month] [year]]] 

Jednak bez względu na to, jak grałem z add_argument_group i add_mutually_exclusive_group,

#!/usr/bin/env python 

import argparse 

def main(opt): 
    print(opt) 

if __name__ == '__main__': 

    parser = argparse.ArgumentParser() 
    bar = parser.add_mutually_exclusive_group() 
    bar.add_argument('-s', action='store_true', default=True) 
    bar.add_argument('-m', action='store_true', default=False) 

    #bar = parser.add_argument_group() 
    bar = parser.add_mutually_exclusive_group() 
    bar.add_argument('-y', metavar='year', type=int, 
        dest='iy', nargs='?', default=0) 
    baz = bar.add_argument_group() 
    g_13 = baz.add_mutually_exclusive_group() 
    g_13.add_argument('-1', dest='i1', 
         help='Display single month output.', 
         action='store_true', default=True) 
    g_13.add_argument('-3', dest='i3', 
         help='Display prev/current/next month output.', 
         action='store_true', default=False) 
    #aaa = bar.add_argument_group() 
    baz.add_argument(metavar='month', type=int, 
         choices=range(1, 13), 
         dest='mo', nargs='?', default=1) 
    baz.add_argument(metavar='year', type=int, 
         dest='yr', nargs='?', default=2000) 

    main(parser.parse_args()) 

mogę tylko zarządzać: Nie można grupować [-y [year]] i [[-1 | -3] [month] [year]] w wykluczającą się grupę. Nie rozumiem dlaczego. Czy ktoś mógłby pomóc? Dzięki.

+0

Możliwe duplikaty http://stackoverflow.com/questions/17909294/python-argparse-mutual-exclusive-group – ronakg

Odpowiedz

4

Grupy argumentów pomagają w zorganizowaniu wyświetlania pomocy. Nie można ich zagnieżdżać. Wzajemnie wykluczające się grupy testują argumenty i modyfikują wyświetlanie użycia. Mogą być zagnieżdżone, ale wynik końcowy jest taki sam jak w przypadku utworzenia jednej dużej grupy. http://bugs.python.org/issue11588 próbuje utworzyć grupę o bardziej ogólnym przeznaczeniu: usage.

W międzyczasie można napisać niestandardową linię użycia i przetestować argumenty po analizie, jeśli wzajemnie wykluczające się grupy nie dają wystarczającej kontroli.


Oto parser za pomocą kodu, który Zajmuję dla http://bugs.python.org/issue11588

parser = argparse.ArgumentParser(formatter_class=argparse.UsageGroupHelpFormatter) 

bar = parser.add_usage_group(kind='mxg', dest='s|m') 
bar.add_argument('-s', action='store_true', default=True) 
bar.add_argument('-m', action='store_true', default=False) 

bar = parser.add_usage_group(kind='mxg', dest='year|more') 
bar.add_argument('-y', metavar='year', type=int,...) 

baz = bar.add_usage_group(kind='any', dest='', joiner=' ', parens='[]') 

g_13 = baz.add_usage_group(kind='mxg', dest='1|3') 
g_13.add_argument('-1', dest='i1',...) 
g_13.add_argument('-3', dest='i3',...) 

baz.add_argument(metavar='month', type=int,...) 
baz.add_argument(metavar='year', type=int,...) 

Zastępuje mutually_exclusive_group z usage_group które mogą być zagnieżdżone, i można przetestować innych stosunków logicznych oprócz „xor”. "każdy" akceptuje dowolną kombinację swoich argumentów, tak jak oczekiwałeś działania "grupy argumentów".

Powstały użycia:

usage: prog.py [-h] [-s | -m] [-y [year] | [[-1 | -3] month year]] [month] 
      [year] 

Główną winą jest wyświetlacz z positionals, „miesiąc” i „rok”. Są we właściwym miejscu w grupie "dowolne", ale wyświetlają się również w zwykłym położeniu końcowym dla pozycji.

Akceptuje wejść typu:

'' 
'-y 1943 -s 
'-1 12 1943' 
'12 1943' 
'12' 
'-3' 

'1943' gives an error, because it it is out of range for a month 

Jak widać rozszerza pojęcie grup nie jest trywialne. Myślę, że jestem na dobrej drodze, ale nadal są ostre krawędzie.

+0

Myślałem, że add_mutually_exclusive_group jest szczególnym przypadkiem add_argument_group. Twoja add_usage_group wydaje się być alternatywą dla add_argument_group? –

+0

MEGroup jest podklasą ArgumentGroup, ale nakładanie się dwóch klas jest minimalne. Ich użycie jest tak różne, że mogą one równie dobrze być oddzielnymi podklasami nadrzędnego '_ActionsContainer' (który jest również super dla' ArgumentParser'). Moja 'UsageGroup' jest uogólnieniem idei' MEGroup'. – hpaulj

+0

Dzięki za wyjaśnienia. Zgadzam się, że MEGroup i ArgumentGroup powinny być osobnymi podklasami _ActionContainer. Być może następne wydanie argparse w Pythonie 3.5 będzie zawierać Twoją implementację. Dobra robota! –