2012-06-17 30 views
14

我在寫一個使用Argparse的命令行工具,並添加了一堆sub_parsers(子命令)。在幫助菜單中,它們出現在一個名爲「commands」的組下面,我會列出所有可能的選項。出現這個名單之前。然而,所有相同的命令下,組標題出現在大括號像這樣:Argparse python,刪除幫助菜單中的子分析器列表

Commands: 
    {foo, bar} 

    foo   - foo does foo 
    bar   - bar does bar 

我想刪除它出現在括號中的冗餘條目。它只出現在這個充滿了sub_parsers的組裏。

我的代碼來處理這看起來像這樣:(其中解析器是ArgumentParser()實例)

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

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

我看了看屬性和我的命令行動小組的方法和似乎無法找到任何能夠爲我解決這個問題的東西(至少從我能理解的角度來看)。我不確定是否有其他人處理過這個問題,我意識到這可能有點模糊。再次,我想要做的就是找到方法來刪除出現在大括號中的冗餘命令列表。

回答

11

的 「{FOO,酒吧}」 的部分是參數 'metavar'。 metavar是argparse如何引用用法和幫助字符串中的預期參數值。 argparse將子命令(如帶有多個選項的參數)視爲如此,如果不指定metavar,則缺省值是大括號中的選項列表(子命令)。它讓用戶知道子命令的可能選項,但是因爲它們在下面列出,所以它是多餘的,如果你有很多子命令,那很醜陋。

您可以輕鬆地用自己的選擇metavar取代:

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

完美,恰好我需要什麼!謝謝。 –

+0

仍然不可能完全刪除該標頭。 'argparse'離開空行。 –

+1

@anatolytechtonik看到我下面的破解。 – Naitree

1

跳水後真正深入到argparse源代碼,我構建了一個破解去除多餘{cmd1,...}選擇列表。

該破解實現了一個自定義幫助格式化程序,它在處理 子分析程序操作時修改了HelpFormatter的格式化方法。具體而言,它會刪除子命令參數組中的子分析器metavarhelp行,並刪除這些子命令的額外縮進 。

請小心使用

蛇皮3版,與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']) 

蛇皮版本2測試,並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']) 

示例輸出:

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

我做了一些有點類似 - http://techtonik.rainforce.org/2016/11/help-formatting-problem-with-argparse.html - 我認爲''arparse'痛苦的正確方法是導出其所有數據在一步之內,然後只是格式化這些數據,而不是調用大量的黑客。 –