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

46 投票
5 回答
24136 浏览
提问于 2025-04-16 14:35
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. model-m MODEL, --model MODEL 在同一行显示,而不是在我运行带有 -h 选项的脚本时,它们出现在不同的行上?

5 个回答

2

如果你给你的 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
)
9

受到@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来提醒你,这样格式化器就会保持不变。这应该让代码在实际应用中更可靠。

我欢迎任何建议,让这个代码看起来更符合Python的风格。

50

你可以提供一个 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

撰写回答