Argparse:可选参数指定时忽略多个位置参数
我正在尝试让 argparse 忽略两个通常需要的参数,当我指定一个可选参数(-l
)时,这两个参数就不需要被评估了。
简单来说,我想实现类似于 --help 的效果:当你指定 -h
时,所有缺失的必需参数都会被忽略。
示例代码:
parser = argparse.ArgumentParser(description="Foo bar baz")
parser.add_argument('arg1', help='arg1 is a positional argument that does this')
parser.add_argument('arg2', help='arg2 is a positional argument that does this')
parser.add_argument('-l', '--list', dest='list', help='this is an optional argument that prints stuff')
options, args = parser.parse_args()
if options.list:
print "I list stuff"
当然,如果我现在运行它,我会得到:
error: too few arguments
我尝试了不同的方法,比如 nargs='?'
,但没有找到有效的解决方案。
这个问题也很相似,但没有得到回答。
6 个回答
到目前为止,我找到的最简单的方法是把解析过程分成两个阶段。首先检查一下是否有 -l/--list
这个选项:
parser = argparse.ArgumentParser(description="Foo bar baz")
parser.add_argument('-l', '--list', dest='list', action='store_true',
help='this is an optional argument that prints stuff')
options, remainder = parser.parse_known_args()
现在,由于你使用了 parse_known_args
,到这里为止不会出现错误,你可以决定如何处理剩下的参数:
if options.list:
print "I list stuff"
else:
parser = argparse.ArgumentParser(add_help=False)
parser.add_argument('arg1', help='arg1 is a positional argument that does this')
parser.add_argument('arg2', help='arg2 is a positional argument that does this')
options = parser.parse_args(remainder)
你可能想在第一个解析器中设置使用说明选项,这样帮助信息看起来会更好一些。
我遇到了这个问题,所以决定使用子命令。虽然子命令可能有点复杂,但如果你发现你的程序在很多情况下没有使用某些位置参数(就像我遇到的那样),那么使用子命令可能是个不错的解决办法。
对于你给出的例子,我会使用类似下面的代码:
parser = argparse.ArgumentParser(description="Foo bar baz")
subparsers = parser.add_subparsers(description='available subcommands')
parser_main = subparsers.add_parser('<main_command_name>')
parser_main.add_argument('arg1', help='arg1 is a positional argument that does this')
parser_main.add_argument('arg2', help='arg2 is a positional argument that does this')
parser_list = subparsers.add_parser('list', help='this is a subcommand that prints stuff')
options, args = parser.parse_args()
我省略了一些你可能想要包含的细节(比如 set_defaults(func=list)
),这些在argparse 文档中有提到。
很遗憾,argparse
的灵活性不够,不能完全满足这个需求。你能做的最好的办法就是把 arg1
和 arg2
设置为可选参数,使用 nargs="?"
,然后自己检查这些参数是否被提供。
内部的 help
功能是通过在命令行中遇到 -h
或 --help
时,立即打印帮助信息并退出程序来实现的。你可以自己写一个类似的功能,比如:
class MyAction(argparse.Action):
def __call__(self, parser, values, namespace, option_string):
print "Whatever"
parser.exit()
(警告:这段代码没有经过测试!)
不过,这种做法确实有一些缺点。帮助信息会毫无条件地显示 arg1
和 arg2
是必填参数。而且,当命令行遇到 -l
或 --list
时,解析过程会直接停止,忽略后面的任何参数。这种行为对于 --help
来说是可以接受的,但对于其他选项来说就不太理想了。