Python Argparse:nargs='+';

Python Argparse:nargs='+';,python,argparse,Python,Argparse,我试着在图像之间做数学运算。我已经定义了(真实代码的简化版本): 该代码生成: arith.py -h usage: arith.py [-h] input1 [input1 ...] operation input2 [input2 ...] 所以它确实理解input1可以包含一个或多个元素,操作将是单个的,input2可以是任意数量的元素 当然,问题是,如果有两个位置参数的元素数量不确定,argparse会混淆什么是什么。我曾尝试将choices=[“+”、“-”、“*”、“/”]添加到“

我试着在图像之间做数学运算。我已经定义了(真实代码的简化版本):

该代码生成:

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加在一起,然后分开寻找“+”、“-”、“/”、“*”,但在做这么难看的事情之前,我想到了利用集体思维

如果您使用了“必需的可选”参数,您就可以实现这一点。如果从左操作数更改为右操作数,则需要在命令行上显示选项。例如

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

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

re.match('(A+)(A)(A+)','AAAAAAAAA')
这将产生
(aaaaa),(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
(我想)

请注意,
选项列表中不包含“-”。这是因为解析器将其视为前缀\u char。也许有一种方法可以把它作为参数值偷偷地放进去,但我不会花时间去找到它

我在解析器中将
input1
值转换为整数。以后你可以这样做。当然,要做彩车

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


但也许更好的解决方案是将所有值作为一个列表,然后自己将其拆分。至少在这3个参数中,您没有充分利用
argparse
power

alist = ['1','2','3','+','4','5','6']
i = <find index of '+-/*'>
input1 = alist[:i]
operations = alist[i]
input2 = alsits[i+1:]
alist=['1'、'2'、'3'、'+'、'4'、'5'、'6']
i=
input1=alist[:i]
操作=列表[i]
输入2=alsits[i+1:]

我不确定
argparse
是否适合您在这里所做的工作。直接通过
sys.argv
可能更容易。嗨,克尔伍德。实际上,我使用argparse解析sys.argv。这为用户“免费”提供了帮助,并为我检查了所有类型和现有变量。直接执行sys.argv就像我的解决方案,将input1、operation和input2汇集在一起,然后将自己分离。可行,但丑陋;)。无论如何谢谢你
argparse
可以构造这样的帮助消息,但这并不意味着它可以按照您想要的方式实际解析参数。如果我调用了
arith.py a b c d e f g
,哪个是
操作
?它可以是
b
f
中的任何一个
argparse
没有任何内置的回溯模式匹配器;它只是以一种贪婪的方式从左到右处理参数。也许有一种更清晰的方法来构造参数。如何处理
input1
input2
?是否使用指定的运算符将
input1
k
th元素与
input2
k
th元素配对?或者计算两个列表的笛卡尔乘积,并将运算符应用于乘积的每个元素?或者别的什么?如果len(input1)=len(input2),它们将配对。如果len(input2)=1,则使用input2的单个元素对input1的所有元素执行操作。谢谢,Dunes,但这并不完全是我要找的。我希望参数是位置的。否则,我将回到将input1、input2和操作放在一起并在内部分离的想法。感谢您的努力。在过去,我唯一能够在非位置参数中插入“-”的方法是:-o“-”,因此前面有空格的字符串,因此,-被视为字符串的一部分,指定像
#
这样的其他内容作为前缀字符,可能会释放出
-
用作参数。是的,hpaulj,这是我采用的方法,正如我在作品中所暗示的,似乎我要求的太多了。不过,为了让用户更清楚,我只留下了这三个参数。解析之后,我再次将它们连接起来,并正确地拆分它们。
namespace(input1=[1,3,4], operation='+', input2=[5,6,7])
alist = ['1','2','3','+','4','5','6']
i = <find index of '+-/*'>
input1 = alist[:i]
operations = alist[i]
input2 = alsits[i+1:]