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



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

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可以包含一个或多个元素,operation将是单个元素,而input2可以包含任意数量的元素。

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

请注意,使用nargs='*'使用多个位置参数通常没有多大意义

我想我可以把参数加在一起。input1, arg游戏。操作和参数。input2和我自己分开寻找"+","-","/","*",但在做一些如此丑陋的事情之前,我想利用集体的思想。

当将字符串分配给位置时,解析器只区分以前缀字符开头的字符串(例如:'-')等。它无法区分表示"数字"的字符串和表示"操作"的字符串。实际上,它执行以下regex操作:

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

into (I think)

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

注意choices列表中不包含'-'。这是因为解析器将其视为prefix_char。可能有一种方法可以将它作为参数值偷偷地插入,但我不打算花时间去寻找它。

我在解析器中将input1值转换为整数。你可以之后再做。当然,用浮点数代替。

我省略了type=str, action='store'等默认参数。


但也许更好的解决方案是将所有值作为一个列表,并自己拆分它。至少有了这3个参数,你没有使用太多argparse的功能。

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

如果您使用"required optional"参数,则可以使此工作。这将需要命令行上的选项来显示何时从左操作数更改为右操作数。如:

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(" ")))

相关内容

  • 没有找到相关文章

最新更新