Python argparser重复子解析 [英] Python argparser repeat subparse

查看:20
本文介绍了Python argparser重复子解析的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 pythons(2.7.2) argparse (1.1) 来解析命令行,我想要的是创建子解析器并使多次输入子解析器命令成为可能.像这样:

I'm using pythons(2.7.2) argparse (1.1) to parse command line and what I want is to create subparser and make it possible to enter subparser commands multiple times. Like this:

./script.py version 1 --file 1 2 3 version 3 --file 4 5 6

有可能创造出这样的东西吗?因为现在当我尝试在结果命名空间中使用此类参数运行脚本时,会得到:

Is it possible to create such thing? Because now when I try to run script with such arguments in result namespase a get:

Namespace(file=['4', '5', '6'], n=[1])

n 它是一个版本号.所以我得到第一个版本号和第二个文件列表,而不是文件列表和版本.

n it is a version number. So I get first version number and second list of files instead both file lists and versions.

推荐答案

对于主解析器来说,子解析器参数是一个可以选择的位置.但它也将所有剩余的参数字符串分配给子解析器.

To the main parser, the subparsers argument is a positional that takes choices. But it also allocates ALL of the remaining argument strings to the subparser.

我希望您的字符串解析如下:

I expect that your string is parsed as follows:

./script.py version 1 --file 1 2 3 version 3 --file 4 5 6

version 被接受为子解析器名称.1 被接受为位置参数 n 的值.(子解析器的).--file 被接受为可选参数(由子解析器).第二次调用的值会覆盖第一次调用的值.我猜 --filenargs='*'.如果是这样,第一个将 ['1','2','3','version','3'] 写入命名空间,而第二个则用 [' 覆盖它4','5','6'].如果 nargs=3,我希望子解析器在第二个 version 上阻塞,它会将其视为未知位置.

version is accepted as a subparser name. 1 is accepted as value to positional argument n. (of the subparser). --file is accepted as a optional argument (by the subparser). The values from the second invocation overwrite the values from the first. I'm guessing --file has nargs='*'. If so, the first one writes ['1','2','3','version','3'] to the namespace, while the second overwrites it with ['4','5','6']. If nargs=3, I would expect the subparser to choke on the second version, which it would see as an unknown positional.

所以基本点是 - 一旦版本"子解析器获得参数列表,它在解析完所有可以解析的内容之前不会放手.在这种情况下,它解析两个 --file 出现.它无法处理的任何事情都会作为UNKNOWNS"返回到主解析器,这通常会引发错误.

So the basic point is - once the 'version' subparser gets the argument list, it does not let go until it has parsed everything it can. In this case it parses both --file occurrences. Anything it can't handle comes back to the main parser as 'UNKNOWNS', which normally raises an error.

如果您想要重复选项的值,请使用附加操作

If you want values from repeated optionals, use an append action

parser.add_argument('--foo',action='append', nargs=3)

import argparse
parser = argparse.ArgumentParser()
sp = parser.add_subparsers(dest='version')
spp = sp.add_parser('version')
spp.add_argument('n',nargs='*',type=int)
spp.add_argument('--file',nargs=3,action='append')
str = 'version 1 --file 1 2 3 version 3 --file 4 5 6'
print(parser.parse_known_args(str.split()))

生产

(Namespace(file=[['1', '2', '3'], ['4', '5', '6']], n=[1], version='version'), ['version', '3'])

仍然只调用一次 version 子解析器,但所有数据都存在.

Still only one call to version subparser, but all the data is present.

另一种方法是嵌套子解析器

A different approach would be to nest subparsers

parser = argparse.ArgumentParser()
sp = parser.add_subparsers(dest='sub')
spp = sp.add_parser('version')
spp.add_argument('n',nargs=1,type=int)
spp.add_argument('--file',nargs=3)

sp = spp.add_subparsers(dest='sub1')
spp = sp.add_parser('version')
spp.add_argument('n1',nargs=1,type=int)
spp.add_argument('--file',dest='file1',nargs=3)

str = 'version 1 --file 1 2 3 version 3 --file 4 5 6'
print(parser.parse_args(str.split()))

请注意,我必须更改dest"以避免覆盖值.这会产生

Note that I have to change the 'dest' to avoid over writing values. This produces

Namespace(file=['1', '2', '3'], file1=['4', '5', '6'], n=[1], n1=[3], sub='version', sub1='version')

这篇关于Python argparser重复子解析的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆