我正在使用pythons(2.7.2)argparse(1.1)来解析命令行,我想要的是创建subparser并使得可以多次输入subparser命令。像这样:
./script.py version 1 --file 1 2 3 version 3 --file 4 5 6
有可能创造这样的东西吗?因为现在当我尝试在结果namespase中使用这样的参数运行脚本时get:
Namespace(file=['4', '5', '6'], n=[1])
这是版本号。所以我获得了第一个版本号和第二个文件列表,而不是文件列表和版本。
答案 0 :(得分:5)
对于主解析器,subparsers参数是一个采取选择的位置。但它也将所有剩余的参数字符串分配给subparser。
我希望您的字符串解析如下:
./script.py version 1 --file 1 2 3 version 3 --file 4 5 6
version
被接受为subparser名称。 1
被接受为位置参数n
的值。 (subparser)。 --file
被接受为可选参数(由subparser提供)。第二次调用的值会覆盖第一次调用的值。我猜--file
有nargs='*'
。如果是,则第一个将['1','2','3','version','3']
写入命名空间,而第二个用['4','5','6']
覆盖它。如果nargs=3
,我希望subparser会阻塞第二个version
,它会看到它是一个未知的位置。
所以基本点是 - 一旦'version'子分析器得到参数列表,它就不会放弃,直到它解析了它可以做的一切。在这种情况下,它会解析--file
次出现。它无法处理的任何东西都会以“UNKNOWNS”的形式返回到主解析器,这通常会引发错误。
如果您想要重复选项的值,请使用追加操作
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
subparser,但所有数据都存在。
另一种方法是嵌套子分析器
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'以避免过度写入值。这会产生
Namespace(file=['1', '2', '3'], file1=['4', '5', '6'], n=[1], n1=[3], sub='version', sub1='version')