2014-07-08 2 views
5

Sto cercando di implementare la seguente:come add_argument_group a add_mutually_exclusive_group con python argparse

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

Tuttavia, non importa come ho giocato con add_argument_group e 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()) 

posso solo gestire:

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

Cioè, non posso gruppo [-y [year]] e [[-1 | -3] [month] [year]] in un gruppo mutuamente esclusivo. Non riesco a capire perché. Qualcuno potrebbe aiutare? Grazie.

+0

Possibile duplicato di http://stackoverflow.com/questions/17909294/python-argparse-mutual-exclusive-group – ronakg

risposta

4

I gruppi di argomenti aiutano solo a organizzare la visualizzazione della guida. Non possono essere annidati. Gruppi mutuamente esclusivi testano argomenti e modificano la visualizzazione dell'uso. Possono essere annidati, ma il risultato finale è lo stesso di un gruppo grande. http://bugs.python.org/issue11588 sta tentando di creare un gruppo usage per scopi più generali.

Nel frattempo è possibile scrivere una riga di utilizzo personalizzata e testare gli argomenti dopo l'analisi, se i gruppi che si escludono a vicenda non forniscono un controllo sufficiente.


Ecco un codice parser usando che sto sviluppando per 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,...) 

Questo sostituisce mutually_exclusive_group con usage_group che possono essere nidificate, e può provare per altre relazioni logiche, oltre a 'xor'. 'any' kind accetta qualsiasi combinazione dei suoi argomenti, proprio come ci si aspettava che il 'argument_group' agisse.

L'utilizzo che ne risulta è:

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

La colpa principale è la visualizzazione delle positionals, 'mese' e 'l'anno'. Sono nel posto giusto nel gruppo 'qualsiasi', ma vengono visualizzati anche nella posizione finale finale per i posizionali.

accetta ingressi come:

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

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

Come si può vedere espandendo il concetto di gruppi non è banale. Penso di essere sulla strada giusta, ma ci sono ancora spigoli.

+0

Ho pensato che add_mutually_exclusive_group è un caso speciale di add_argument_group. Il tuo add_usage_group sembra l'alternativa a add_argument_group? –

+0

MEGroup è una sottoclasse di ArgumentGroup, ma la sovrapposizione tra le 2 classi è minima. Il loro uso è così diverso che potrebbero anche essere sottoclassi separate del genitore '_ActionsContainer' (che è anche super per' ArgumentParser'). Il mio 'UsageGroup' è una generalizzazione dell'idea' MEGroup'. – hpaulj

+0

Grazie per i chiarimenti. Sono d'accordo che MEGroup e ArgumentGroup dovrebbero essere sottoclassi separate di _ActionContainer. Forse la prossima versione di argparse in Python 3.5 incorporerà la tua implementazione. Buon lavoro! –