Argparse 建议在帮助文本使用行中使用无意义的顺序
Argparse suggests nonsensical order in help text usage line
这个节目:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('files', metavar='INPUT', nargs='*',
help='File(s) containing words to include. If none given, stdin will be used.')
parser.add_argument('-x', '--exclude', nargs='*',
help='File(s) containing words to exclude.')
args = parser.parse_args()
print args.files
print args.exclude
在 Python 2.7.9:
中 运行 时产生此输出
$ python prog.py --help
usage: prog.py [-h] [-x [EXCLUDE [EXCLUDE ...]]] [INPUT [INPUT ...]]
positional arguments:
INPUT File(s) containing words to include. If
none given, stdin will be used.
optional arguments:
-h, --help show this help message and exit
-x [EXCLUDE [EXCLUDE ...]], --exclude [EXCLUDE [EXCLUDE ...]]
File(s) containing words to exclude.
但是,"help" 输出指示用户对参数使用无意义的排序。这是荒谬的,因为如果使用 -x
选项,则不会检测到 INPUT
个参数。
Argparse 应该改为建议用户使用此顺序:
usage: prog.py [-h] [INPUT [INPUT ...]] [-x [EXCLUDE [EXCLUDE ...]]]
两个问题:
- 这是
argparse
中的错误吗? (我认为是。)
- 不管它是否是一个错误,我怎样才能修复它以便
$ python prog.py --help
输出我想要的帮助文本(见上文),最好是尽可能 DRY 的方式?
最简单的方法是将usage="..."
添加到argparse.ArgumentParser()
。
通过查看 argparse 的源代码,我找到了一种求助于可能有点脏的参数的方法:
class MyHelpFormatter(argparse.HelpFormatter):
def _format_actions_usage(self, actions, groups):
actions.sort(key=lambda a: bool(a.option_strings and a.nargs != 0))
return super(MyHelpFormatter, self)._format_actions_usage(actions, groups)
parser = argparse.ArgumentParser(formatter_class = MyHelpFormatter)
在输入选项中添加'-f', '--files'
:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('-f', '--files', metavar='INPUT', nargs='*', required=True,
help='File(s) containing words to include. If none given, stdin will be used.')
parser.add_argument('-x', '--exclude', nargs='*',
help='File(s) containing words to exclude.')
args = parser.parse_args()
print args.files
显示:
usage: argparse_test.py [-h] [-f [INPUT [INPUT ...]]]
[-x [EXCLUDE [EXCLUDE ...]]]
optional arguments:
-h, --help show this help message and exit
-f [INPUT [INPUT ...]], --files [INPUT [INPUT ...]]
File(s) containing words to include. If none given,
stdin will be used.
-x [EXCLUDE [EXCLUDE ...]], --exclude [EXCLUDE [EXCLUDE ...]]
File(s) containing words to exclude.
print args.exclude
您可以将 'files' 设为必需。来自文档:
In general, the argparse module assumes that flags like -f and --bar indicate optional arguments, which can always be omitted at the command line. To make an option required, True can be specified for the required= keyword argument to add_argument():
生成 usage
行时,带标记的参数放在最前面,位置在后面。这符合常见的命令行用法。它不会努力评估这是否是最佳选择。
解决此问题的最简单方法是提供自定义 usage
参数。
(关于更改使用行中参数顺序的问题。解决方案需要自定义 HelpFormatter
class。
)
正如您所注意到的,当 * 位置放在 * 可选之后时,所有参数都分配给可选。您可以使用 '--'
来分隔两个参数列表。
有一个带有补丁的 bug/issue 当 positional
采用已知数量的参数(例如默认参数)时应该改进处理。它通过注意到位置需要一个参数来做到这一点,因此它为它保留了一个。但是在 * *
的情况下, positional
满足 none,因此它无法知道如何在 2.
之间拆分参数
我喜欢将 postional
变成标记论点的想法。这应该可以减少许多 *
参数中固有的歧义。
这个节目:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('files', metavar='INPUT', nargs='*',
help='File(s) containing words to include. If none given, stdin will be used.')
parser.add_argument('-x', '--exclude', nargs='*',
help='File(s) containing words to exclude.')
args = parser.parse_args()
print args.files
print args.exclude
在 Python 2.7.9:
中 运行 时产生此输出$ python prog.py --help
usage: prog.py [-h] [-x [EXCLUDE [EXCLUDE ...]]] [INPUT [INPUT ...]]
positional arguments:
INPUT File(s) containing words to include. If
none given, stdin will be used.
optional arguments:
-h, --help show this help message and exit
-x [EXCLUDE [EXCLUDE ...]], --exclude [EXCLUDE [EXCLUDE ...]]
File(s) containing words to exclude.
但是,"help" 输出指示用户对参数使用无意义的排序。这是荒谬的,因为如果使用 -x
选项,则不会检测到 INPUT
个参数。
Argparse 应该改为建议用户使用此顺序:
usage: prog.py [-h] [INPUT [INPUT ...]] [-x [EXCLUDE [EXCLUDE ...]]]
两个问题:
- 这是
argparse
中的错误吗? (我认为是。) - 不管它是否是一个错误,我怎样才能修复它以便
$ python prog.py --help
输出我想要的帮助文本(见上文),最好是尽可能 DRY 的方式?
最简单的方法是将usage="..."
添加到argparse.ArgumentParser()
。
通过查看 argparse 的源代码,我找到了一种求助于可能有点脏的参数的方法:
class MyHelpFormatter(argparse.HelpFormatter):
def _format_actions_usage(self, actions, groups):
actions.sort(key=lambda a: bool(a.option_strings and a.nargs != 0))
return super(MyHelpFormatter, self)._format_actions_usage(actions, groups)
parser = argparse.ArgumentParser(formatter_class = MyHelpFormatter)
在输入选项中添加'-f', '--files'
:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('-f', '--files', metavar='INPUT', nargs='*', required=True,
help='File(s) containing words to include. If none given, stdin will be used.')
parser.add_argument('-x', '--exclude', nargs='*',
help='File(s) containing words to exclude.')
args = parser.parse_args()
print args.files
显示:
usage: argparse_test.py [-h] [-f [INPUT [INPUT ...]]]
[-x [EXCLUDE [EXCLUDE ...]]]
optional arguments:
-h, --help show this help message and exit
-f [INPUT [INPUT ...]], --files [INPUT [INPUT ...]]
File(s) containing words to include. If none given,
stdin will be used.
-x [EXCLUDE [EXCLUDE ...]], --exclude [EXCLUDE [EXCLUDE ...]]
File(s) containing words to exclude.
print args.exclude
您可以将 'files' 设为必需。来自文档:
In general, the argparse module assumes that flags like -f and --bar indicate optional arguments, which can always be omitted at the command line. To make an option required, True can be specified for the required= keyword argument to add_argument():
生成 usage
行时,带标记的参数放在最前面,位置在后面。这符合常见的命令行用法。它不会努力评估这是否是最佳选择。
解决此问题的最简单方法是提供自定义 usage
参数。
(关于更改使用行中参数顺序的问题。解决方案需要自定义 HelpFormatter
class。
正如您所注意到的,当 * 位置放在 * 可选之后时,所有参数都分配给可选。您可以使用 '--'
来分隔两个参数列表。
有一个带有补丁的 bug/issue 当 positional
采用已知数量的参数(例如默认参数)时应该改进处理。它通过注意到位置需要一个参数来做到这一点,因此它为它保留了一个。但是在 * *
的情况下, positional
满足 none,因此它无法知道如何在 2.
我喜欢将 postional
变成标记论点的想法。这应该可以减少许多 *
参数中固有的歧义。