2012-06-17 11 views
14

Piszę narzędzie wiersza poleceń za pomocą Argparse i dodałem kilka sub_parsers (podrzędne polecenia). W menu pomocy pojawiają się one pod grupą o nazwie "komendy", a ja dostaję ładną listę wszystkich możliwych opcji. Jednak zanim pojawi się ta lista, wszystkie te same polecenia pojawiają się pod nazwą grupy w nawiasach tak:Python argparse, usuń listę akapitów w menu pomocy

Commands: 
    {foo, bar} 

    foo   - foo does foo 
    bar   - bar does bar 

Chcę usunąć zbędne wpisy, które pojawiają się w nawiasach. Pojawia się tylko w tej grupie, która jest wypełniona sub_parsers.

Mój kod do obsługi to wygląda tak: (gdzie parser jest ArgumentParser() instancji)

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

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

Sprawdziliśmy atrybutów i metod działania polecenia mojej grupy i nie może wydawać się znajdź wszystko, co rozwiąże to dla mnie (przynajmniej z tego, co mogę zrozumieć). Nie jestem pewien, czy ktoś inny sobie z tym poradził, zdaję sobie sprawę, że to chyba trochę niejasne. I znowu, wszystko, co próbuję zrobić, to znaleźć sposób na usunięcie nadmiarowej listy poleceń, które pojawiają się w nawiasach klamrowych.

Odpowiedz

11

Stała "{foo, bar}" część jest argument 'metavar'. Metavar to sposób, w jaki argparse odnosi się do oczekiwanych wartości argumentów w łańcuchach użycia i pomocy. argparse traktuje podkomendy jak argument z wieloma opcjami, więc jeśli nie określisz metavaru, domyślną listą będzie lista opcji (podkomend) w nawiasach klamrowych. Pozwala użytkownikowi poznać możliwe opcje dla podkomend, ale ponieważ są one wymienione poniżej, są zbędne i jeśli masz dużo podkomend, jest to brzydkie.

można łatwo zastąpić własnymi wybranego metavar:

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

Perfect, dokładnie czego potrzebowałem! Dzięki. –

+0

Nie można całkowicie usunąć tego nagłówka. 'argparse' opuszcza pustą linię. –

+1

@anatolytechtonik Zobacz mój hack poniżej. – Naitree

1

Po nurkowaniu naprawdę głęboko w kodzie źródłowym argparse, mam skonstruował włamać usunąć nadmiarowe listy {cmd1,...} wyborem.

Hack implementuje niestandardowy formant pomocy, który modyfikuje metody formatowania HelpFormatter, gdy mamy do czynienia z działaniem o wartościach odczynników . W szczególności usuwa on linię rzędów w grupie podpoleceń i usuwa dodatkowe wcięcia tych podkomend.

Proszę używać z ostrożnością.

Wersja python 3, testowane z 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']) 

wersji python 2, przetestowane z 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']) 

Przykładowe wyjście:

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

Zrobiłem to trochę podobnie - http://techtonik.rainforce.org/2016/11/help-formatting-problem-with-argparse.html - i myślę, że właściwym sposobem na ból "arparse" jest eksportowanie wszystkich jego danych w jednym kroku, a następnie po prostu sformatuj te dane, zamiast wywoływać wiele hacków. –

Powiązane problemy