控制argparse帮助参数列表的格式?

时间:2011-03-28 17:42:38

标签: python argparse

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

如何打印参考。模型-m MODEL, --model MODEL在同一行,而不是在我使用-h选项运行脚本时出现在另一行?

5 个答案:

答案 0 :(得分:25)

您可以提供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的未来版本中停止工作。提交功能请求,以便为http://bugs.python.org/

上的max_help_position自定义提供公共界面

输出

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

答案 1 :(得分:1)

受@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_wideTypeError标记,格式化程序将保持不变。这应该使代码对于已部署的应用程序更加可靠。

我欢迎提出任何建议以使其更具Pythonic性。

答案 2 :(得分:0)

我没有python 3,但是看OptionParser(非常相似),我注意到你可以改变:

parser.formatter.max_help_position = 50

这将增加为选项标志保留的空间(默认为24)

答案 3 :(得分:0)

另一种方法:劫持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 :(得分:0)

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

parser = argparse.ArgumentParser(formatter_class=help_formatter)

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

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