Argparse:两个位置参数,其中nargs ='+'

时间:2015-05-14 10:51:40

标签: python argparse

我正在尝试在图像之间进行数学运算。我已定义(我的真实代码的简化版本):

parser = argparse.ArgumentParser(description='Arithmetic operations on images')
parser.add_argument("input1", metavar='input1', action='store',
      help='list of input images to operate with', nargs="+", type=str)
parser.add_argument("operation", metavar='operation', action='store', type=str, 
      help='type of operation (+,-,*,/) to be done', nargs=1)
parser.add_argument("input2",metavar='input2', action='store', nargs="+", 
      type=str, help='image (or value) with which to perform the operation on input1')

此代码生成:

arith.py -h
usage: arith.py [-h] input1 [input1 ...] operation input2 [input2 ...]

所以它确实理解input1可以包含一个或多个元素,操作将是单个元素,input2可以是任意数量的元素。

问题当然是,有两个位置参数,元素数量不确定,argparse会混淆什么。我已经尝试将choices = [“+”,“ - ”,“*”,“/”]添加到'operation',这样它就知道在哪里进行分离,但似乎argparse无法做到。实际上,在argparse文档中,谈论nargs ='*'你可以读到:

  

请注意,使用nargs ='*'

获得多个位置参数通常没有多大意义

我原以为我可以将args.input1,args.operation和args.input2加在一起并将自己分开寻找“+”,“ - ”,“/”,“*”,但在做一些如此丑陋的事情之前我考虑挖掘集体思想。

2 个答案:

答案 0 :(得分:1)

当将字符串分配给位置时,解析器仅区分以前缀char开头的那些(例如' - ')和其余的。它无法区分代表'数字'和那些代表'操作'。实际上它执行此正则表达式操作:

re.match('(A+)(A)(A+)','AAAAAAAAA')

会产生(AAAAAA),(A),(A)。它为最后两组分配足够的字符串以满足它们的规范,并将其余的分配给第一组。

所以你需要某种标志'标记第一个列表的结尾。

我认为,这是你与argparse最接近的地方:

parser.add_argument("input1", nargs="+", type=int)
parser.add_argument("-o", "--operation", choices=['+','minus','*','/'] )
parser.add_argument("input2", nargs="+", type=int)

哪个应该转

PROG 1 3 4 -o + 5 6 7
PROG 1 3 4 -o+ 5 6 7
PROG 1 3 4 --operation=+ 5 6 7
进入(我认为)

namespace(input1=[1,3,4], operation='+', input2=[5,6,7])

请注意,choices的列表不包含' - '。这是因为解析器将其视为prefix_char。可能有一种方法可以将其作为参数值隐藏起来,但我不会花时间去寻找它。

我将input1值转换为解析器中的整数。你可以在那之后做到。当然还要制作漂浮物。

我省略了type=straction='store'等默认参数。

但也许更好的解决方案是将所有值作为1个列表,并自行拆分。至少有这三个论点,你并没有充分利用argparse权力。

alist = ['1','2','3','+','4','5','6']
i = <find index of '+-/*'>
input1 = alist[:i]
operations = alist[i]
input2 = alsits[i+1:]

答案 1 :(得分:0)

如果使用“必需的可选”参数,则可以使其工作。如果要求命令行上的选项显示何时从左操作数更改为操作以更改为正确的操作数。例如

import argparse

parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument("--left-operands", "-l", nargs="+", required=True)
parser.add_argument("--right-operands", "-r", nargs="+", required=True)
parser.add_argument("--operation", "-o", choices=["+", "-", "*", "/"], required=True)

argline = "-l 1 2 -o + -r 3 4"

print(parser.parse_args(argline.split(" ")))