首页 > 解决方案 > Python argparse:增加参数和描述之间的空间

问题描述

我将 Python3argparse用于复杂的命令行界面。很多争论,其中一些是“冗长的”以避免误解。

parser = argparse.ArgumentParser(description='Command-line interface')
parser.add_argument('--long-param-one',
                    help='Long param one description',
                    dest='lond_param_one',
                    required=True)

parser.add_argument('--long-param-two',
                    help='Long param two description',
                    dest='lond_param_two',
                    required=True)

当参数名称足够长并且目标变量也足够长时,当您调用脚本时,它会导致难看的格式--help

Command-line interface

optional arguments:
  -h, --help            show this help message and exit
  --long-param-one LONG_PARAM_ONE
                        Long param one description
  --long-param-two LONG_PARAM_TWO
                        Long param two description

我的意思是,参数和值在一个字符串上,描述在另一个字符串上,即使控制台右侧有足够的空间以便将其放在一行中。就像第一个参数--help一样。当你有 30-40 个参数时,命令行帮助的可读性真的变差了

标签: pythonpython-3.xargparse

解决方案


argparse默认情况下限制 option+metavar 占用的最大空间,并将帮助消息写在单独的行上,即使终端足够大以容纳两者。

考虑这个示例脚本:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--name', help='help help')
parser.add_argument('--parameter', help='help help')
parser.add_argument('--parameter-name', help='help help')
parser.add_argument('--this-parameter-name', help='help help')
parser.add_argument('--this-is-parameter-name', help='help help')
parser.add_argument('--this-is-a-parameter-name', help='help help')
parser.add_argument('--this-is-a-long-parameter-name', help='help help')
parser.add_argument('--this-is-a-very-long-parameter-name', help='help help')
parser.add_argument('--this-is-a-very-very-long-parameter-name', help='help help')
parser.add_argument('--this-is-a-very-very-very-long-parameter-name', help='help help')

parser.parse_args()

结果如下:

usage: a.py [-h] [--name NAME] [--parameter PARAMETER]
            [--parameter-name PARAMETER_NAME]
            [--this-parameter-name THIS_PARAMETER_NAME]
            [--this-is-parameter-name THIS_IS_PARAMETER_NAME]
            [--this-is-a-parameter-name THIS_IS_A_PARAMETER_NAME]
            [--this-is-a-long-parameter-name THIS_IS_A_LONG_PARAMETER_NAME]
            [--this-is-a-very-long-parameter-name THIS_IS_A_VERY_LONG_PARAMETER_NAME]
            [--this-is-a-very-very-long-parameter-name THIS_IS_A_VERY_VERY_LONG_PARAMETER_NAME]
            [--this-is-a-very-very-very-long-parameter-name THIS_IS_A_VERY_VERY_VERY_LONG_PARAMETER_NAME]

optional arguments:
  -h, --help            show this help message and exit
  --name NAME           help help
  --parameter PARAMETER
                        help help
  --parameter-name PARAMETER_NAME
                        help help
  --this-parameter-name THIS_PARAMETER_NAME
                        help help
  --this-is-parameter-name THIS_IS_PARAMETER_NAME
                        help help
  --this-is-a-parameter-name THIS_IS_A_PARAMETER_NAME
                        help help
  --this-is-a-long-parameter-name THIS_IS_A_LONG_PARAMETER_NAME
                        help help
  --this-is-a-very-long-parameter-name THIS_IS_A_VERY_LONG_PARAMETER_NAME
                        help help
  --this-is-a-very-very-long-parameter-name THIS_IS_A_VERY_VERY_LONG_PARAMETER_NAME
                        help help
  --this-is-a-very-very-very-long-parameter-name THIS_IS_A_VERY_VERY_VERY_LONG_PARAMETER_NAME
                        help help

尝试避免此问题的最简单方法是metavar显式指定并使用短值,因此THIS_IS_A_VERY_VERY_VERY_LONG_PARAMETER_NAME您可以使用ov 代替X. 例如:

import argparse

parser = argparse.ArgumentParser()
m = 'X'
parser.add_argument('--name', help='help help', metavar=m)
parser.add_argument('--parameter', help='help help', metavar=m)
parser.add_argument('--parameter-name', help='help help', metavar=m)
parser.add_argument('--this-parameter-name', help='help help', metavar=m)
parser.add_argument('--this-is-parameter-name', help='help help', metavar=m)
parser.add_argument('--this-is-a-parameter-name', help='help help', metavar=m)
parser.add_argument('--this-is-a-long-parameter-name', help='help help', metavar=m)
parser.add_argument('--this-is-a-very-long-parameter-name', help='help help', metavar=m)
parser.add_argument('--this-is-a-very-very-long-parameter-name', help='help help', metavar=m)
parser.add_argument('--this-is-a-very-very-very-long-parameter-name', help='help help', metavar=m)

parser.parse_args()

结果是:

usage: a.py [-h] [--name X] [--parameter X] [--parameter-name X]
            [--this-parameter-name X] [--this-is-parameter-name X]
            [--this-is-a-parameter-name X] [--this-is-a-long-parameter-name X]
            [--this-is-a-very-long-parameter-name X]
            [--this-is-a-very-very-long-parameter-name X]
            [--this-is-a-very-very-very-long-parameter-name X]

optional arguments:
  -h, --help            show this help message and exit
  --name X              help help
  --parameter X         help help
  --parameter-name X    help help
  --this-parameter-name X
                        help help
  --this-is-parameter-name X
                        help help
  --this-is-a-parameter-name X
                        help help
  --this-is-a-long-parameter-name X
                        help help
  --this-is-a-very-long-parameter-name X
                        help help
  --this-is-a-very-very-long-parameter-name X
                        help help
  --this-is-a-very-very-very-long-parameter-name X
                        help help

这已经好很多了,但是正如您所看到的,参数名称很长,它仍然不会将所有文本写在一行上。

实现您想要的唯一方法是指定 aformatter_class并使用该问题max_help_position中描述的。然而,这不是模块公共 API 的一部分。我不知道他们什么时候没有向公共 API 添加至少几个有用的参数。

您可能仍然想指定一个metavar

import argparse

formatter = lambda prog: argparse.HelpFormatter(prog,max_help_position=52)
parser = argparse.ArgumentParser(formatter_class=formatter)
m = 'X'
parser.add_argument('--name', help='help help', metavar=m)
parser.add_argument('--parameter', help='help help', metavar=m)
parser.add_argument('--parameter-name', help='help help', metavar=m)
parser.add_argument('--this-parameter-name', help='help help', metavar=m)
parser.add_argument('--this-is-parameter-name', help='help help', metavar=m)
parser.add_argument('--this-is-a-parameter-name', help='help help', metavar=m)
parser.add_argument('--this-is-a-long-parameter-name', help='help help', metavar=m)
parser.add_argument('--this-is-a-very-long-parameter-name', help='help help', metavar=m)
parser.add_argument('--this-is-a-very-very-long-parameter-name', help='help help', metavar=m)
parser.add_argument('--this-is-a-very-very-very-long-parameter-name', help='help help', metavar=m)

parser.parse_args()

输出将是:

usage: a.py [-h] [--name X] [--parameter X] [--parameter-name X]
            [--this-parameter-name X] [--this-is-parameter-name X]
            [--this-is-a-parameter-name X] [--this-is-a-long-parameter-name X]
            [--this-is-a-very-long-parameter-name X]
            [--this-is-a-very-very-long-parameter-name X]
            [--this-is-a-very-very-very-long-parameter-name X]

optional arguments:
  -h, --help                                        show this help message and
                                                    exit
  --name X                                          help help
  --parameter X                                     help help
  --parameter-name X                                help help
  --this-parameter-name X                           help help
  --this-is-parameter-name X                        help help
  --this-is-a-parameter-name X                      help help
  --this-is-a-long-parameter-name X                 help help
  --this-is-a-very-long-parameter-name X            help help
  --this-is-a-very-very-long-parameter-name X       help help
  --this-is-a-very-very-very-long-parameter-name X  help help

您可能会尝试确定终端的大小(大多数终端提供一个WIDTHCOLUMNSenv 变量可能对此有用)以确定max_help_position在这种情况下最好的值。


要在一行上提供所有参数帮助(假设终端足够大),您需要:

max_help_position >= max(len(param.name)+len(param.metavar) for param in params)

推荐阅读