【问题标题】:Control formatting of the argparse help argument list?控制 argparse 帮助参数列表的格式?
【发布时间】:2011-07-24 16:31:00
【问题描述】:
import argparse
parser = argparse.ArgumentParser(prog='tool')
args = [('-u', '--upf', 'ref. upf', dict(required='True')),
        ('-s', '--skew', 'ref. skew', {}),
        ('-m', '--model', 'ref. model', {})]
for args1, args2, desc, options in args:  
     parser.add_argument(args1, args2, help=desc, **options)

parser.print_help()

输出:

usage: capcheck [-h] -u UPF [-s SKEW] [-m MODEL]

optional arguments:
  -h, --help            show this help message and exit
  -u UPF, --upf UPF     ref. upf
  -s SKEW, --skew SKEW  ref. skew
  -m MODEL, --model MODEL
                        ref. model

如何打印 ref.当我使用-h 选项运行脚本时,模型-m MODEL, --model MODEL 位于同一行,而不是出现在单独的行上?

【问题讨论】:

    标签: python argparse


    【解决方案1】:

    您可以提供formatter_class 参数:

    parser = argparse.ArgumentParser(prog='tool',
      formatter_class=lambda prog: argparse.HelpFormatter(prog,max_help_position=27))
    
    args = [('-u', '--upf', 'ref. upf', dict(required='True')),
            ('-s', '--skew', 'ref. skew', {}),
            ('-m', '--model', 'ref. model', {})]
    for args1, args2, desc, options in args:  
         parser.add_argument(args1, args2, help=desc, **options)
    
    parser.print_help()
    

    注意:argparse.HelpFormatter 的实现是私有的,只有名称是公共的。因此,该代码可能会在 argparse 的未来版本中停止工作。提交功能请求,为max_help_positionhttp://bugs.python.org/上的自定义提供公共接口

    输出

    usage: tool [-h] -u UPF [-s SKEW] [-m MODEL]
    
    optional arguments:
      -h, --help               show this help message and exit
      -u UPF, --upf UPF        ref. upf
      -s SKEW, --skew SKEW     ref. skew
      -m MODEL, --model MODEL  ref. model
    

    【讨论】:

      【解决方案2】:

      受@jfs 回答的启发,我想出了这个解决方案:

      def make_wide(formatter, w=120, h=36):
          """Return a wider HelpFormatter, if possible."""
          try:
              # https://stackoverflow.com/a/5464440
              # beware: "Only the name of this class is considered a public API."
              kwargs = {'width': w, 'max_help_position': h}
              formatter(None, **kwargs)
              return lambda prog: formatter(prog, **kwargs)
          except TypeError:
              warnings.warn("argparse help formatter failed, falling back.")
              return formatter
      

      有了它,你可以用任何你喜欢的HelpFormatter 调用它:

      parser = argparse.ArgumentParser(
          formatter_class=make_wide(argparse.ArgumentDefaultsHelpFormatter)
      )
      

      parser = argparse.ArgumentParser(
          formatter_class=make_wide(argparse.HelpFormatter, w=140, h=20)
      )
      

      这样做是为了确保可以使用widthmax_help_position 参数实际创建更广泛的格式化程序。如果私有 API 发生更改,make_wide 将通过 TypeError 进行注释,并且格式化程序返回不变。这应该使代码对于已部署的应用程序更加可靠。

      我欢迎任何建议让这更 Pythonic。

      【讨论】:

        【解决方案3】:

        另一种方法:劫持 sys.argv,检查它的 --help 和 -h,如果找到,使用 argparse.format_help 提取帮助文本,按摩它,打印它,然后退出。

        import  sys, re, argparse 
        
        RGX_MID_WS = re.compile(r'(\S)\s{2,}')
        
        def main(argv):
        
        #   note add_help = False
            parser = argparse.ArgumentParser(description = '%(prog)s: testing help mods', formatter_class= argparse.RawTextHelpFormatter, add_help = False)
        
            parser.add_argument('bar', nargs='+', help='two bars that need to be frobbled')
            parser.add_argument('--foo', action='store_true', help='foo the bars before frobbling\nfoo the bars before frobbling')
            parser.add_argument('--xxxxx', nargs=2, help='many xes')
            parser.add_argument('--bacon', help ='a striped food')
            parser.add_argument('--badger', help='in a striped pyjamas')
            parser.add_argument('--animal', dest='animal', choices=('zabra', 'donkey', 'bat') ,help ='could be one of these')
        
        #   may exit
            lArgs = help_manage(parser)
            args = parser.parse_args() # args = lArgs
        
            print('bars are: ', args.bar)
        
        
        def help_manage(parser):
            """
            check for -h, --help, -h in a single-letter cluster;
            if none found, return, otherwise clean up help text and exit
            """
        
            lArgs = sys.argv[1:]
            lArgsNoHelp = [sOpt for sOpt in lArgs if (not sOpt in ('--help', '-h')) and not (sOpt[0] == '-' and sOpt[1] != '-' and 'h' in sOpt)]
        
        #   no change?  then no --help params
            if len(lArgsNoHelp) == len(lArgs): return
        
            sHelp = parser.format_help()
        
        #   to see help as formated by argparse, uncomment: 
        #   print(sHelp)
        #   exit() 
        
            for sLine in sHelp.split('\n'): print(clean_line(sLine))
        
            exit() 
        
        def clean_line(sLine):
            """
            this is just an example, and goes nowhere near covering all possible
            argument properties
            """
        #   avoid messing with usage: lines
            if 'usage' in sLine: return sLine
            if sLine.startswith('  ') and '[' in sLine: return sLine
        
            if sLine.endswith(' arguments:'): return sLine + '\n'
        
            sLine = sLine.lstrip()
        
            sLine = RGX_MID_WS.sub(r'\1\n', sLine)
            if sLine.startswith('-'): sLine = '\n' + sLine
            return sLine.replace('{', '\n(can be: ').replace('}', ')').replace('\n\n', '\n')
        
        if __name__ == '__main__':
        
            bRes =  main(sys.argv[1:])
            sys.exit(bRes)
        

        帮助不格式化:

        usage: argparse_fix_min2.py [--foo] [--xxxxx XXXXX XXXXX] [--bacon BACON]
                                        [--badger BADGER] [--animal {zabra,donkey,bat}]
                                        bar [bar ...]
        
            argparse_fix_min2.py: testing help mods
        
            positional arguments:
              bar                   two bars that need to be frobbled
        
            optional arguments:
              --foo                 foo the bars before frobbling
                                    foo the bars before frobbling
              --xxxxx XXXXX XXXXX   many xes
              --bacon BACON         a striped food
              --badger BADGER       in a striped pyjamas
              --animal {zabra,donkey,bat}
                                    could be one of these
        
        

        带格式:

        usage: argparse_fix_min2.py [--foo] [--xxxxx XXXXX XXXXX] [--bacon BACON]
                                        [--badger BADGER] [--animal {zabra,donkey,bat}]
                                        bar [bar ...]
        
            argparse_fix_min2.py: testing help mods
        
            positional arguments:
        
            bar
            two bars that need to be frobbled
        
            optional arguments:
        
        
            --foo
            foo the bars before frobbling
            foo the bars before frobbling
        
            --xxxxx XXXXX XXXXX
            many xes
        
            --bacon BACON
            a striped food
        
            --badger BADGER
            in a striped pyjamas
        
            --animal 
            (can be: zabra,donkey,bat)
            could be one of these
        
            """
        
        

        【讨论】:

          【解决方案4】:

          如果您向您的ArgumentParser 提供自定义formatter_class

          parser = argparse.ArgumentParser(formatter_class=help_formatter)
          

          然后使用子解析器,格式化程序将仅适用于顶级帮助消息。为了对所有子解析器使用相同(或其他)格式化程序,您需要为每个 add_parser 调用提供 formatter_class 参数:

          subparsers = parser.add_subparsers(metavar="ACTION", dest="action")
          child_parser = subparsers.add_parser(
              action_name, formatter_class=help_formatter
          )
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-09-24
            • 2021-11-25
            • 1970-01-01
            • 2011-05-21
            • 1970-01-01
            • 2013-04-10
            • 1970-01-01
            • 2020-10-12
            相关资源
            最近更新 更多