【问题标题】:Python argparse argument order in help text帮助文本中的 Python argparse 参数顺序
【发布时间】:2020-10-12 13:53:59
【问题描述】:

我的 Python 程序使用 argparse 模块接受命令行参数,它按预期工作,但是,帮助文本有点误导,我想为使用我的程序的其他人修复它。

目前,我有一个位置参数,它是一个目录和一个可选参数-p,它使用add_argument 函数的nargs=+ 参数接受任意数量的包名称。 DIR 位置参数需要在可选参数列表之前指定,否则该目录将被错误地添加到包名称列表中,并且会出错说没有指定位置参数。帮助输出当前如下所示:

package_info.py --help
usage: package_info.py [-h] [-v] [--no-cache] [-g FILE] [-p [PKG [PKG ...]]]
                       DIR

Get information on packages in ros workspace.

positional arguments:
  DIR                   The directory containing rospackages.

optional arguments:
  -h, --help            show this help message and exit
  -v, --verbose         Enables verbose mode
  --no-cache            Do not cache the dependency graph
  -g FILE, --graph-file FILE
                        The graph file to load from or save to.
  -p [PKG [PKG ...]], --packages [PKG [PKG ...]]
                        The packages to provide information on.

我希望它被格式化为在 -p 标志之前显示 DIR,以便用户更清楚地知道必须首先指定此参数,如下所示:

package_info.py --help
usage: package_info.py DIR [-h] [-v] [--no-cache] [-g FILE] [-p [PKG [PKG ...]]]
            .
            .
            .

package_info.py --help
usage: package_info.py DIR
                       [-h] [-v] [--no-cache] [-g FILE] [-p [PKG [PKG ...]]]
            .
            .
            .

是否有一种简单的方法来格式化帮助消息,或者我需要编写自定义帮助消息格式化程序吗?

【问题讨论】:

    标签: python parameter-passing command-line-arguments argparse


    【解决方案1】:

    您说的是usage 行。

    使用格式化程序确实将positionals 分开并将它们放在最后,如果足够长的话,可能会放在它们自己的行上。是的,确实与处理“+”标记的参数有冲突。不应该,但是修复太复杂了,不能简单地插入。

    我不建议更改使用格式化程序 - 这组方法太复杂(且脆弱)而无法轻松修补。

    在定义ArgumentParser 时提供自定义usage 参数将是最简单的解决方法。我不记得它是如何与换行交互的。

    【讨论】:

      【解决方案2】:

      查看answer provided by hpaulj 之后,我能够查看python3.5 的源代码,argparse 1.1 版,这是我系统上的版本,并找到了几行我可以修改以使其工作的代码。当然,这不是一个优雅的解决方案,而是灵活的(随着程序的发展,我不断添加/删除/修改命令行参数)并且可以快速实施。

      我创建了一个继承自 argparse.HelpFormatter 类的自定义帮助格式化程序类。在我的自定义类中,我复制了_format_usage 函数并更改了以下几行:

      # build full usage string
      format = self._format_actions_usage
      action_usage = format(optionals + positionals, groups)
      usage = ' '.join([s for s in [prog, action_usage] if s])
      

      # build full usage string
      format = self._format_actions_usage
      action_usage = format(positionals + optionals, groups)
      usage = ' '.join([s for s in [prog, action_usage] if s])
      

      如果不需要对文本进行换行,这将为我提供所需的格式。

      我还更改了以下内容:

      # if prog is short, follow it with optionals or positionals
      if len(prefix) + len(prog) <= 0.75 * text_width:
          indent = ' ' * (len(prefix) + len(prog) + 1)
          if opt_parts:
              lines = get_lines([prog] + opt_parts, indent, prefix)
              lines.extend(get_lines(pos_parts, indent))
          elif pos_parts:
              lines = get_lines([prog] + pos_parts, indent, prefix)
          else:
              lines = [prog]
      

      # if prog is short, follow it with optionals or positionals
      if len(prefix) + len(prog) <= 0.75 * text_width:
          indent = ' ' * (len(prefix) + len(prog) + 1)
          if pos_parts:
              lines = get_lines([prog] + pos_parts, indent, prefix)
              lines.extend(get_lines(opt_parts, indent))
          elif opt_parts:
              lines = get_lines([prog] + opt_parts, indent, prefix)
          else:
              lines = [prog]
      

      这为我提供了需要包装时所需的格式。

      【讨论】:

        猜你喜欢
        • 2021-08-13
        • 2013-03-08
        • 2016-03-14
        • 1970-01-01
        • 2011-05-21
        • 2012-02-20
        • 2013-07-02
        • 2012-08-29
        • 2012-10-16
        相关资源
        最近更新 更多