Python argparse:将可选参数与nargs组合=argparse.remaine

2024-06-25 23:08:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我一定漏掉了一些明显的东西。目标是使用argparse,其中第一个参数是必需的,第二个是可选的,其余任何参数都是可选的。在

为了说明这个问题,我制作了两个测试解析器;它们之间唯一的区别是使用nargs=argparse.remaine其中一个是nargs,另一个是'*'。在

def doParser1(argsin):
    parser = argparse.ArgumentParser(description='Parser demo.')
    parser.add_argument('req1', help='first required parameter')
    parser.add_argument('--opt1', help='first optional parameter')
    parser.add_argument('leftovers', nargs=argparse.REMAINDER,
                    help='all the other parameters')
    argsout = parser.parse_args(args=argsin)
    print argsout
    return argsout

def doParser2(argsin):
    parser = argparse.ArgumentParser(description='Parser demo.')
    parser.add_argument('req1', help='first required parameter')
    parser.add_argument('--opt1', help='first optional parameter')
    parser.add_argument('leftovers', nargs='*',
                    help='all the other parameters')
    argsout = parser.parse_args(args=argsin)
    print argsout
    return argsout

如果没有额外的参数,parser2可以工作。这是parser1和parser 1后面的输入:

^{pr2}$

如果有额外的参数,则parser1中缺少opt1值,parser2只会混淆:

input: ['req1value', '--opt1', 'opt1value', 'r1', 'r2']
Namespace(leftovers=['--opt1', 'opt1value', 'r1', 'r2'], opt1=None, req1='req1value')
usage: py-argparse.py [-h] [--opt1 OPT1]
                  [-leftovers [LEFTOVERS [LEFTOVERS ...]]]
                  req1
py-argparse.py: error: unrecognized arguments: r1 r2

预期产出应为:

Namespace(leftovers=['r1', 'r2'], opt1='opt1value', req1='req1value')

看起来这应该是一个简单的例子,这里的内容是从我真正想做的事情中简化出来的。我试着让剩菜成为可选的,添加了各种其他的选择,但没有什么比这更好的了。在

任何帮助都将不胜感激。在


Tags: addparser参数parameterargparsehelpargsargument
3条回答

当一个或多个位置是“零或多个”类型(? * REMAINDER)时,位置和选项的相互混合是很棘手的。简单的解决办法是不要把它们混在一起——先给出选项,然后再给出所有的位置。在

事情是这样的:

input: ['req1value', ' opt1', 'opt1value']
Namespace(leftovers=[' opt1', 'opt1value'], opt1=None, req1='req1value')

由于req1value字符串,解析器首先解析位置。req1想要1个字符串,leftovers获取其他所有内容,包括 opt1。在

^{pr2}$

对于*leftovers满足于{},没有字符串,因此None(实际上我得到[])。 opt1被解析为可选的。在

input: ['req1value', ' opt1', 'opt1value', 'r1', 'r2']
...
py-argparse.py: error: unrecognized arguments: r1 r2

如前所述,*leftovers被设置为[]-opt1已处理。但现在有2根弦没有地方放。您希望它们进入leftovers,但这已经被使用了。如果leftovers是{},那么它将按照您的预期使用它们。在

关键是当它试图解析第一个位置时,它也会尽可能地解析所有的位置。在一个层面上,parse_args正在做re.match('(A)(A*)','AOA')产生('A', '')的群体。在

有2个建议的补丁程序来处理这个问题。一个使用2个步骤parse_known_args来实现选项和位置的完全混合。这是optparse的用户可能会想到的那种行为。在

另一个补丁试图延迟处理可以接受0参数字符串http://bugs.python.org/issue15112的位置。在

opt1必须在“unnamed”参数之前。真正的测试用例应该是:

    [' opt1', 'opt1value', 'req1value']

以及

^{pr2}$

您可以使用parse_known_args

import argparse
parser = argparse.ArgumentParser(description='Parser demo.')
parser.add_argument('req1', help='first required parameter')
parser.add_argument(' opt1', help='first optional parameter')

args, leftovers = parser.parse_known_args(['req1value', ' opt1', 'opt1value'])
print(args, leftovers)
# (Namespace(opt1='opt1value', req1='req1value'), [])

args, leftovers = parser.parse_known_args(['req1value', ' opt1', 'opt1value', 'r1', 'r2'])
print(args, leftovers)
# (Namespace(opt1='opt1value', req1='req1value'), ['r1', 'r2'])

相关问题 更多 >