如何在 argparse 中使用带有 nargs='*' 参数的可选位置参数?
Posted
技术标签:
【中文标题】如何在 argparse 中使用带有 nargs=\'*\' 参数的可选位置参数?【英文标题】:How to use optional positional arguments with nargs='*' arguments in argparse?如何在 argparse 中使用带有 nargs='*' 参数的可选位置参数? 【发布时间】:2017-02-23 07:13:59 【问题描述】:如下代码所示,我想有一个可选的位置参数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')
【问题讨论】:
argparse
怎么知道/path/to/file1
与files
而不是bar
?
【参考方案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'
【讨论】:
以上是关于如何在 argparse 中使用带有 nargs='*' 参数的可选位置参数?的主要内容,如果未能解决你的问题,请参考以下文章
argparse 错误: 'nargs 必须是 %r 才能提供 const' % OPTIONAL)