Argparse:必填参数在“可选参数”下列出?
我用下面这段简单的代码来解析一些参数;注意其中有一个是必填的。不过,当用户运行这个脚本却没有提供这个参数时,显示的使用说明/帮助文本并没有指出有一个参数是必填的,这让我觉得很困惑。我该怎么做才能让Python显示出这个参数是必填的呢?
以下是代码:
import argparse
if __name__ == '__main__':
parser = argparse.ArgumentParser(
description='Foo')
parser.add_argument('-i','--input', help='Input file name', required=True)
parser.add_argument('-o','--output', help='Output file name', default="stdout")
args = parser.parse_args()
print ("Input file: %s" % args.input )
print ("Output file: %s" % args.output )
当运行上面的代码而没有提供必填参数时,我得到以下输出:
usage: foo.py [-h] -i INPUT [-o OUTPUT]
Foo
optional arguments:
-h, --help show this help message and exit
-i INPUT, --input INPUT
Input file name
-o OUTPUT, --output OUTPUT
Output file name
7 个回答
你不需要去重写可选的组。
只需要这样做:
parser = argparse.ArgumentParser()
required = parser.add_argument_group('required arguments')
required.add_argument('--required_arg', required=True)
# All arguments set via parser directly will automatically go to the optional group
parser.add_argument('--optional_arg')
parser.print_help()
这会输出:
usage: [-h] --required_arg REQUIRED_ARG [--optional_arg OPTIONAL_ARG]
optional arguments:
-h, --help show this help message and exit
--optional_arg OPTIONAL_ARG
required arguments:
--required_arg REQUIRED_ARG
如果你想要把必填参数放在可选参数前面,可以这样做:
parser = argparse.ArgumentParser()
optional = parser._action_groups.pop()
required = parser.add_argument_group('required arguments')
parser._action_groups.append(optional)
required.add_argument('--required_arg', required=True)
optional.add_argument('--optional_arg')
parser.print_help()
这样会按正确的顺序输出组:
usage: [-h] --required_arg REQUIRED_ARG [--optional_arg OPTIONAL_ARG]
required arguments:
--required_arg REQUIRED_ARG
optional arguments:
-h, --help show this help message and exit
--optional_arg OPTIONAL_ARG
再来一次,基于@RalphyZ的内容
这个方法不会破坏公开的API。
from argparse import ArgumentParser, SUPPRESS
# Disable default help
parser = ArgumentParser(add_help=False)
required = parser.add_argument_group('required arguments')
optional = parser.add_argument_group('optional arguments')
# Add back help
optional.add_argument(
'-h',
'--help',
action='help',
default=SUPPRESS,
help='show this help message and exit'
)
required.add_argument('--required_arg', required=True)
optional.add_argument('--optional_arg')
这个方法的效果和上面的一样,并且应该能在未来的版本中继续使用:
usage: main.py [-h] [--required_arg REQUIRED_ARG]
[--optional_arg OPTIONAL_ARG]
required arguments:
--required_arg REQUIRED_ARG
optional arguments:
-h, --help show this help message and exit
--optional_arg OPTIONAL_ARG
这是基于 @Karl Rosaen 的内容进行的扩展。
parser = argparse.ArgumentParser()
optional = parser._action_groups.pop() # Edited this line
required = parser.add_argument_group('required arguments')
# remove this line: optional = parser...
required.add_argument('--required_arg', required=True)
optional.add_argument('--optional_arg')
parser._action_groups.append(optional) # added this line
return parser.parse_args()
运行后会输出:
usage: main.py [-h] [--required_arg REQUIRED_ARG]
[--optional_arg OPTIONAL_ARG]
required arguments:
--required_arg REQUIRED_ARG
optional arguments:
-h, --help show this help message and exit
--optional_arg OPTIONAL_ARG
因为我喜欢把必需的参数放在可选参数之前,所以我采用了一些小技巧来实现这个目的:
parser = argparse.ArgumentParser()
parser._action_groups.pop()
required = parser.add_argument_group('required arguments')
optional = parser.add_argument_group('optional arguments')
required.add_argument('--required_arg', required=True)
optional.add_argument('--optional_arg')
return parser.parse_args()
这样输出的结果是:
usage: main.py [-h] --required_arg REQUIRED_ARG [--optional_arg OPTIONAL_ARG]
required arguments:
--required_arg REQUIRED_ARG
optional arguments:
--optional_arg OPTIONAL_ARG
我可以接受不在可选参数组里显示 -h, --help
这个选项。
以 -
或 --
开头的参数通常被认为是可选的。而其他的参数则是位置参数,这些参数是必须提供的,就像函数的参数一样。虽然可以让可选参数变成必需的,但这有点违背了它们的设计初衷。因为它们仍然属于非位置参数,所以即使它们是必需的,仍然会在“可选参数”的标题下列出。不过,在用法部分缺少的方括号表明它们实际上是必需的。
你可以查看 文档了解更多信息:
一般来说,argparse 模块认为像 -f 和 --bar 这样的标志表示可选参数,这些参数在命令行中可以随时省略。
注意:必需的选项通常被认为是不太好的做法,因为用户通常期望选项是可选的,因此应该尽量避免使用。
话虽如此,帮助信息中的 “位置参数” 和 “可选参数” 这两个标题是由两个参数组自动生成的,参数会被自动分开。你可以“黑客”一下,改变可选参数的名称,但更优雅的解决方案是为“必需的命名参数”创建另一个组(或者你想叫它什么都可以):
parser = argparse.ArgumentParser(description='Foo')
parser.add_argument('-o', '--output', help='Output file name', default='stdout')
requiredNamed = parser.add_argument_group('required named arguments')
requiredNamed.add_argument('-i', '--input', help='Input file name', required=True)
parser.parse_args(['-h'])
usage: [-h] [-o OUTPUT] -i INPUT
Foo
optional arguments:
-h, --help show this help message and exit
-o OUTPUT, --output OUTPUT
Output file name
required named arguments:
-i INPUT, --input INPUT
Input file name