2012-06-17 9 views
14

Sto scrivendo un'utilità da riga di comando usando Argparse e ho aggiunto un gruppo di sub_parser (sottocomandi). Nel menu di aiuto compaiono sotto un gruppo chiamato "comandi" e ottengo una bella lista di tutte le opzioni possibili. Tuttavia prima che appaia questa lista, tutti gli stessi comandi appaiono sotto il titolo del gruppo tra parentesi graffe in questo modo:Argparse python, rimuovi lista subparser nel menu help

Commands: 
    {foo, bar} 

    foo   - foo does foo 
    bar   - bar does bar 

Voglio rimuovere le voci ridondanti che appaiono tra parentesi graffe. Appare solo in questo gruppo che è pieno di sub_parser.

Il mio codice per gestire questa situazione si presenta in questo modo: (dove è il parser ArgumentParser() istanza)

subparsers = parser.add_subparsers(title="Commands") 

foo = subparsers.add_parser("foo", help="- foo does foo") 
bar = subparsers.add_parser("bar", help="- bar does bar") 

Ho guardato gli attributi e metodi del mio gruppo comandi azione e non riesco a trova tutto ciò che risolverà questo per me (almeno da quello che posso dare un senso). Non sono sicuro che se qualcun altro ha affrontato questo, mi rendo conto che probabilmente è un po 'oscuro. E ancora, tutto quello che sto cercando di fare è trovare il modo di rimuovere la lista ridondante dei comandi che appaiono in parentesi graffe.

risposta

11

Il "{foo, bar}" parte è l'argomento 'metavar'. Una metavar è il modo in cui argparse fa riferimento ai valori degli argomenti previsti nelle stringhe di utilizzo e di aiuto. argparse tratta i sottocomandi come un argomento con scelte multiple, quindi se non si specifica una metavar, il valore predefinito è l'elenco di scelte (sottocomandi) in parentesi graffe. Permette all'utente di conoscere le possibili opzioni per i sottocomandi, ma poiché sono elencati di seguito, è ridondante e se hai molti sottocomandi, è brutto.

Si può facilmente sostituire con la propria metavar scelto:

subparsers = parser.add_subparsers(title="Commands", metavar="<command>") 
+0

perfetto, esattamente quello di cui avevo bisogno! Grazie. –

+0

Non è ancora possibile rimuovere completamente quell'intestazione. 'argparse' lascia la linea vuota. –

+1

@anatolytechtonik Guarda il mio trucco qui sotto. – Naitree

3

È possibile personalizzare la formattazione del messaggio di aiuto scrivendo la propria classe formattatore, in base all'interfaccia argparse.HelpFormatter e passandola al costruttore del parser utilizzando l'argomento formatter_class.

Per maggiori dettagli vedi http://docs.python.org/dev/library/argparse.html#formatter-class

1

Dopo un'immersione davvero in profondità nel codice sorgente argparse, ho costruito un hack per rimuovere la lista ridondante {cmd1,...} scelta.

L'hacking implementa un programma di formattazione della guida personalizzato che modifica i metodi di formattazione di HelpFormatter quando si ha a che fare con l'azione subparser. In particolare, rimuove la subparser metavar e help riga nel gruppo di argomenti del sottocomando e rimuove il rientro extra di tali sottocomandi.

Si prega di usare con attenzione.

La versione pitone 3, controllato con python3.6

from argparse import ArgumentParser, HelpFormatter, _SubParsersAction 

class NoSubparsersMetavarFormatter(HelpFormatter): 

    def _format_action(self, action): 
     result = super()._format_action(action) 
     if isinstance(action, _SubParsersAction): 
      # fix indentation on first line 
      return "%*s%s" % (self._current_indent, "", result.lstrip()) 
     return result 

    def _format_action_invocation(self, action): 
     if isinstance(action, _SubParsersAction): 
      # remove metavar and help line 
      return "" 
     return super()._format_action_invocation(action) 

    def _iter_indented_subactions(self, action): 
     if isinstance(action, _SubParsersAction): 
      try: 
       get_subactions = action._get_subactions 
      except AttributeError: 
       pass 
      else: 
       # remove indentation 
       yield from get_subactions() 
     else: 
      yield from super()._iter_indented_subactions(action) 

parser = ArgumentParser(formatter_class=NoSubparsersMetavarFormatter) 
subparsers = parser.add_subparsers(title="Commands") 

foo = subparsers.add_parser("foo", help="- foo does foo") 
bar = subparsers.add_parser("bar", help="- bar does bar") 

parser.parse_args(['-h']) 

La versione pitone 2, controllato con python2.7

from argparse import ArgumentParser, HelpFormatter, _SubParsersAction 

class NoSubparsersMetavarFormatter(HelpFormatter): 

    def _format_action(self, action): 
     result = super(NoSubparsersMetavarFormatter, 
         self)._format_action(action) 
     if isinstance(action, _SubParsersAction): 
      return "%*s%s" % (self._current_indent, "", result.lstrip()) 
     return result 

    def _format_action_invocation(self, action): 
     if isinstance(action, _SubParsersAction): 
      return "" 
     return super(NoSubparsersMetavarFormatter, 
        self)._format_action_invocation(action) 

    def _iter_indented_subactions(self, action): 
     if isinstance(action, _SubParsersAction): 
      try: 
       get_subactions = action._get_subactions 
      except AttributeError: 
       pass 
      else: 
       for subaction in get_subactions(): 
        yield subaction 
     else: 
      for subaction in super(NoSubparsersMetavarFormatter, 
            self)._iter_indented_subactions(action): 
       yield subaction 

parser = ArgumentParser(formatter_class=NoSubparsersMetavarFormatter) 
subparsers = parser.add_subparsers(title="Commands") 

foo = subparsers.add_parser("foo", help="- foo does foo") 
bar = subparsers.add_parser("bar", help="- bar does bar") 

parser.parse_args(['-h']) 

uscita Esempio:

usage: a.py [-h] {foo,bar} ... 

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

Commands: 
    foo   - foo does foo 
    bar   - bar does bar 
+1

L'ho fatto in qualche modo simile - http://techtonik.rainforce.org/2016/11/help-formatting-problem-with-argparse.html - e penso che il modo corretto per il dolore 'arparse' sia quello di esportare tutti i suoi dati in un solo passaggio e quindi basta formattare questi dati anziché chiamare un sacco di hack. –

Problemi correlati