Python 帮助文本中的 argparse 参数顺序
Python argparse argument order in help text
我的 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 ...]]]
.
.
.
是否有一种简单的方法来格式化帮助消息,或者我是否需要编写自定义帮助消息格式化程序?
你说的是 usage
行。
用法格式化程序确实将 positionals
分开并将它们放在最后,如果足够长,可能在它们自己的行上。是的,确实与处理带有“+”标记的参数冲突。它不应该,但修复太复杂而不能简单地插入。
我不建议更改用法格式化程序 - 这套方法太复杂(而且脆弱),无法轻松修补。
在定义 ArgumentParser
时提供自定义 usage
参数是最简单的解决方法。我不记得它是如何与换行交互的。
查看 后,我能够查看 python3.5 的源代码,argparse 版本 1.1 这是我系统上的版本,并找到了几行我可以修改以使其工作。诚然,这不是一个优雅的解决方案,但很灵活(随着程序的发展,我不断 adding/removing/modifying 命令行参数)并且可以快速实施。
我创建了一个自定义帮助格式化程序 class,它继承自 argparse.HelpFormatter
class。在我的自定义 class 中,我复制了 _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 模块接受命令行参数并且它按预期工作,但是,帮助文本有点误导,我想为使用我的程序的其他人修复它。
目前,我有一个位置参数,它是一个目录和一个可选参数 -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 ...]]]
.
.
.
是否有一种简单的方法来格式化帮助消息,或者我是否需要编写自定义帮助消息格式化程序?
你说的是 usage
行。
用法格式化程序确实将 positionals
分开并将它们放在最后,如果足够长,可能在它们自己的行上。是的,确实与处理带有“+”标记的参数冲突。它不应该,但修复太复杂而不能简单地插入。
我不建议更改用法格式化程序 - 这套方法太复杂(而且脆弱),无法轻松修补。
在定义 ArgumentParser
时提供自定义 usage
参数是最简单的解决方法。我不记得它是如何与换行交互的。
查看
我创建了一个自定义帮助格式化程序 class,它继承自 argparse.HelpFormatter
class。在我的自定义 class 中,我复制了 _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]
这为我提供了需要换行时所需的格式。