帮助文本中的 Python argparse 参数顺序
Posted
技术标签:
【中文标题】帮助文本中的 Python argparse 参数顺序【英文标题】:Python argparse argument order in help text 【发布时间】: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 ...]]]
.
.
.
是否有一种简单的方法来格式化帮助消息,或者我需要编写自定义帮助消息格式化程序吗?
【问题讨论】:
【参考方案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]
这为我提供了需要包装时所需的格式。
【讨论】:
以上是关于帮助文本中的 Python argparse 参数顺序的主要内容,如果未能解决你的问题,请参考以下文章
Python argparse:有没有办法控制帮助文本的空白? [复制]