如何在argparse中使用带有nargs ='*'参数的可选位置参数?

时间:2016-10-14 00:50:45

标签: python parsing argparse optparse optional-arguments

如下面的代码所示,我希望有一个可选的位置参数files,我想为它指定一个默认值,当传入路径时,使用指定的路径。

但是因为--bar可以有多个参数,传入的路径没有进入args.files,我该如何解决?谢谢!

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo')
parser.add_argument('--bar', nargs='*')
parser.add_argument('files', nargs='?')

cmd = '--foo a --bar b c d '
print parser.parse_args(cmd.split())
# Namespace(bar=['b', 'c', 'd'], files=None, foo='a')


cmd = '--foo a --bar b c d /path/to/file1'
print parser.parse_args(cmd.split())
# Namespace(bar=['b', 'c', 'd', '/path/to/file1'], files=None, foo='a')

1 个答案:

答案 0 :(得分:1)

你的论证规范本质上是模棱两可的(因为--bar可以带有无限的参数,没有好的方法来判断它何时结束,特别是因为files是可选的),所以它需要用户消除歧义。具体来说,可以告诉argparse"这是开关部分的结尾,所有后续参数都是位置"将--放在仅位置部分之前。如果你这样做:

cmd = '--foo a --bar b c d -- /path/to/file1'
print parser.parse_args(cmd.split())

你应该得到:

Namespace(bar=['b', 'c', 'd'], files='/path/to/file1', foo='a')

(在Py3上测试过,但也应该适用于Py2)

或者,用户可以通过避免在--bar之后放置位置参数来传递位置参数,例如:

cmd = '/path/to/file1 --foo a --bar b c d'

cmd = '--foo a /path/to/file1 --bar b c d'

最后,考虑到它引入的模糊性,您可以避免使用nargs='*'作为开关。相反,使用每个开关的单个值定义--bar多次接受,将所有用途累积到list

parser.add_argument('--bar', action='append')

然后你多次传递--bar一次提供多个值,而不是传递一次多个值:

cmd = '--foo a --bar b --bar c --bar d /path/to/file1'