Control formatting of the argparse help argument list?

自作多情 提交于 2019-12-03 14:41:22

问题


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()

Output:

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

How do I print ref. model in the same line as -m MODEL, --model MODEL instead of that appearing on a separate line when I run the script with -h option?


回答1:


You could supply formatter_class argument:

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()

Note: Implementation of argparse.HelpFormatter is private only the name is public. Therefore the code might stop working in future versions of argparse. File a feature request to provide a public interface for the customization of max_help_position on http://bugs.python.org/

Output

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:


Inspired by @jfs's answer, I have come up with this solution:

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

Having that, you can call it with any HelpFormatter that you like:

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

or

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

What this does is make sure that the wider formatter can actually be created using the width and max_help_position arguments. If the private API changes, that is noted by make_wide by a TypeError and the formatter is returned unchanged. That should make the code more reliable for deployed applications.

I'd welcome any suggestions to make this more pythonic.



来源:https://stackoverflow.com/questions/5462873/control-formatting-of-the-argparse-help-argument-list

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!