Python 每个位置参数的可选参数

Python 每个位置参数的可选参数,python,argparse,Python,Argparse,使用argparse(或其他什么?)我希望每个位置参数都有一个带有默认值的可选参数 理由如下: script.py arg1 arg2 -o 1 arg3 -o 2 arg4 arg5 我想让它把它解析成一些有用的东西,比如一个位置参数列表和一个填充默认值的可选参数列表。e、 g.如果在上述示例中,可选项的默认值为0: positional = [arg1, arg2, arg3, arg4, arg5] optional = [0, 1, 2, 0, 0] 换句话说,parser.add_

使用argparse(或其他什么?)我希望每个位置参数都有一个带有默认值的可选参数

理由如下:

script.py arg1 arg2 -o 1 arg3 -o 2 arg4 arg5
我想让它把它解析成一些有用的东西,比如一个位置参数列表和一个填充默认值的可选参数列表。e、 g.如果在上述示例中,可选项的默认值为0:

positional = [arg1, arg2, arg3, arg4, arg5]
optional = [0, 1, 2, 0, 0]

换句话说,
parser.add_参数('-o',action='append')
不是我想要的,因为我丢失了位置参数,每个可选参数都与之关联。

下面是我总结的一个简单技巧,可能是一个合理的起点:

import argparse

class PositionalAction(argparse.Action):
    def __call__(self,parser,namespace,values,option_string=None):
        lst = getattr(namespace,self.dest)
        lst.append(values)
        parser.last_positional_values = lst
        all_positional = getattr(namespace,'all_positional',[])
        all_positional.append(lst)
        namespace.all_positional = all_positional

class AssociateAction(argparse.Action):
    def __call__(self,parser,namespace,values,option_string=None):
        try:
            parser.last_positional_values.append(values)
        except AttributeError:
            pass

parser = argparse.ArgumentParser()
parser.add_argument('-o',action=AssociateAction,dest=argparse.SUPPRESS)
junk,unknown = parser.parse_known_args()

for i,_ in enumerate(unknown):
    parser.add_argument('arg%d'%i,action=PositionalAction,default=[])

print parser.parse_args()
这就是行动:

temp $ python test1.py foo -o 1 bar -o 2 baz qux -o 4
Namespace(all_positional=[['foo', '1'], ['bar', '2'], ['baz'], ['qux', '4']], arg0=['foo', '1'], arg1=['bar', '2'], arg2=['baz'], arg3=['qux', '4'])
这个问题有一些挑战。首先,您希望接受任意数量的位置参数——argparse不喜欢这样。argparse想提前知道会发生什么。解决方案是构建一个解析器并解析命令行,但告诉argparse仅解析已知参数(在本例中,非位置的
-o
参数都以静默方式解析,但不解析“位置”参数)
parse\u known\u args
非常适合于此,因为它以
的形式返回元组(namespace\u of\u parsed\u stuff,uknown\u args)
。现在我们知道了未知参数——我们只需要为每个参数向解析器添加一个位置参数,以使parse_args满意

现在,自定义操作实际上在做什么?当找到一个位置参数(在第二遍中)时,我们得到默认值(这是一个列表)并将值添加到该列表中(以下我将称之为“值”列表)。然后,我们使用对“值”列表的引用修改解析器。我们还从名称空间中获取“所有位置”列表。如果它没有那个属性,我们只会得到一个空列表。我们将“value”列表添加到“all_positional”列表中,并将其放回名称空间


现在,当我们点击
-o
标志时,我们查看解析器以获得“值”列表,并将附加值添加到该列表中。我们可以做同样的事情,根本不需要碰解析器。。。(我们可以查看
名称空间。所有位置[-1]
——它与
解析器的列表相同。最后一个位置值
)。

使用
optpasse
,如果稍微复杂一点,它会很强大:

op = optparse.OptionParser(usage=usage)

op.add_option('-c','--cmd',dest='cmd',help="""Command to run. Mutually exclusive with -s. You can use string ${ADDR} to have it replaced with specified host address in the command. """)

op.add_option('-s','--script',dest='script',help="""Script file to run remotely. Mutually exclusive with -c. A script can have its own arguments; specify the whole command in doublequotes, like "script -arg arg".""")

op.add_option('-l','--replicate-owner',dest='replicateowner',action="store_true",help="""Replicate (symbolic) owner and (symbolic) group of the file on the remote host, if possible. If remote account with username the same as local account does not exist on remote host, this will silently fail.""")

# parse cmdline options
(opts, args) = op.parse_args()
opts获取命名参数,args获取位置参数


您可以让位置参数取值或设置true或false以及更多IIRC。

您自己单步通过sys.argv怎么样。您似乎不需要argparse提供的额外功能。例如:

argv='script.py arg1 arg2 -o 1 arg3 -o 2 arg4 arg5'.split()
pos=[]
opt=[]
i=1
while i<len(argv):
    a=argv[i]
    if a[:2]!='-o':
        pos.append(a)
        opt.append(0)
    else:
        i += 1
        opt[-1]=argv[i]
    i += 1
argv='script.py arg1 arg2-o 1 arg3-o 2 arg4 arg5'.split()
pos=[]
opt=[]
i=1

你知道你会有多少个位置参数吗?不知道。不管有多少个参数,我都想循环这些参数。你创造的这个魔术似乎达到了我想要的效果(或者足够接近),但我需要一段时间才能完全理解你所做的。不管怎样,谢谢你!我将补充一些关于正在发生的事情的评论,希望能帮助大家更容易理解。别担心,这些误解肯定更多地是因为我缺乏专业知识,而不是缺乏清晰性。这并不能回答具体问题。海报似乎知道如何使用{opt,arg}解析。