我认为这nargs='*'足以处理可变数量的参数.显然它不是,我不明白这个错误的原因.
代码:
p = argparse.ArgumentParser()
p.add_argument('pos')
p.add_argument('foo')
p.add_argument('--spam', default=24, type=int, dest='spam')
p.add_argument('vars', nargs='*')
p.parse_args('1 2 --spam 8 8 9'.split())
Run Code Online (Sandbox Code Playgroud)
我认为最终的命名空间应该是Namespace(pos='1', foo='2', spam='8', vars=['8', '9']).相反,argparse给出了这个错误:
usage: prog.py [-h] [--spam SPAM] pos foo [vars [vars ...]]
error: unrecognized arguments: 9 8
Run Code Online (Sandbox Code Playgroud)
基本上,argparse不知道在哪里放这些额外的参数......为什么?
Hoa*_*ell 36
对于不知道是什么的人nargs:
nargs 代表 Number Of Arguments
3: 3 个值,可以是您想要的任何数字?: 单个值,可以是可选的*: 一个灵活数量的值,这些值将被收集到一个列表中+: 类似 *,但至少需要一个值 argparse.REMAINDER: 命令行中剩余的所有值例子:
Python
import argparse
my_parser = argparse.ArgumentParser()
my_parser.add_argument('--input', action='store', type=int, nargs=3)
args = my_parser.parse_args()
print(args.input)
Run Code Online (Sandbox Code Playgroud)
安慰
$ python nargs_example.py --input 42
usage: nargs_example.py [-h] [--input INPUT INPUT INPUT]
nargs_example.py: error: argument --input: expected 3 arguments
$ python nargs_example.py --input 42 42 42
[42, 42, 42]
Run Code Online (Sandbox Code Playgroud)
hpa*_*ulj 34
问题相关的Python是问题15112.
argparse: nargs='*'如果前面有一个选项和另一个位置,则位置参数不接受任何项目
当argparse解析['1', '2', '--spam', '8', '8', '9']它时,它首先尝试匹配['1','2']尽可能多的位置参数.使用您的参数,模式匹配字符串是AAA*:1个参数pos和for foo,以及零参数vars(记住*意味着ZERO_OR_MORE).
['--spam','8']由你的--spam论点处理.既然vars已经设定[],没有什么可以处理的['8','9'].
编程更改以argparse检查0参数字符串是否满足模式的情况,但仍有optionals待解析.然后它推迟对该*论点的处理.
您可以通过首先解析输入parse_known_args,然后处理remainder另一个调用来解决这个问题parse_args.
为了完全自由地在位置之间穿插选项,在问题14191中,我建议parse_known_args只使用optionals,然后parse_args只知道位置.parse_intermixed_args我在那里发布的函数可以在ArgumentParser子类中实现,而无需修改argparse.py代码本身.
这是一种处理子分析器的方法.我已经采用了这个parse_known_intermixed_args函数,为了演示而简化它,然后使它parse_known_args成为Parser子类的功能.我不得不采取额外措施来避免递归.
最后我更改了_parser_class子分析器Action,因此每个subparser都使用了这个替代方案parse_known_args.另一种方法是子类化_SubParsersAction,可能修改它__call__.
from argparse import ArgumentParser
def parse_known_intermixed_args(self, args=None, namespace=None):
# self - argparse parser
# simplified from http://bugs.python.org/file30204/test_intermixed.py
parsefn = super(SubParser, self).parse_known_args # avoid recursion
positionals = self._get_positional_actions()
for action in positionals:
# deactivate positionals
action.save_nargs = action.nargs
action.nargs = 0
namespace, remaining_args = parsefn(args, namespace)
for action in positionals:
# remove the empty positional values from namespace
if hasattr(namespace, action.dest):
delattr(namespace, action.dest)
for action in positionals:
action.nargs = action.save_nargs
# parse positionals
namespace, extras = parsefn(remaining_args, namespace)
return namespace, extras
class SubParser(ArgumentParser):
parse_known_args = parse_known_intermixed_args
parser = ArgumentParser()
parser.add_argument('foo')
sp = parser.add_subparsers(dest='cmd')
sp._parser_class = SubParser # use different parser class for subparsers
spp1 = sp.add_parser('cmd1')
spp1.add_argument('-x')
spp1.add_argument('bar')
spp1.add_argument('vars',nargs='*')
print parser.parse_args('foo cmd1 bar -x one 8 9'.split())
# Namespace(bar='bar', cmd='cmd1', foo='foo', vars=['8', '9'], x='one')
Run Code Online (Sandbox Code Playgroud)
cal*_*531 12
简单解决方案:--spam在指定之前指定标志,pos并且foo:
p = argparse.ArgumentParser()
p.add_argument('pos')
p.add_argument('foo')
p.add_argument('--spam', default=24, type=int, dest='spam')
p.add_argument('vars', nargs='*')
p.parse_args('--spam 8 1 2 8 9'.split())
Run Code Online (Sandbox Code Playgroud)
如果--spam在指定变量参数后放置标志,则同样有效.
p = argparse.ArgumentParser()
p.add_argument('pos')
p.add_argument('foo')
p.add_argument('--spam', default=24, type=int, dest='spam')
p.add_argument('vars', nargs='*')
p.parse_args('1 2 8 9 --spam 8'.split())
Run Code Online (Sandbox Code Playgroud)
编辑:对于它的价值,似乎更改*为a +也将修复错误.
p = argparse.ArgumentParser()
p.add_argument('pos')
p.add_argument('foo')
p.add_argument('--spam', default=24, type=int, dest='spam')
p.add_argument('vars', nargs='+')
p.parse_args('1 2 --spam 8 8 9'.split())
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
65902 次 |
| 最近记录: |