Argparse,处理可重复的项目集 [英] Argparse, handle repeatable set of items
问题描述
是否可以创建一组相关且可重复的可选参数?
Is it possible to create a set of optional arguments that are related and repeatable?
比方说,我有三个参数-a,-b,-c组成一个集合, -a是必需的,但是-b和-c是可选的. (已更新)
Let's say I have three arguments -a, -b, -c that form a set, -a is required, but -b and -c are optional. (Updated)
我希望能够指定其中的多个集合.
I would like an ability to specify multiple set of these.
Script.py -a 1 -b 2 -c 3 -a 4 -c 6 -a 7 -b 8 -a 10
这将被解析为字典列表,如下所示:
This will be parsed as a list of dict as follows
[
{"a":1, "b":2, "c":3},
{"a":4, "c":6},
{"a":7, "b":8},
{"a":10}
]
推荐答案
使参数可重复的一种方法是使用'append'操作类型:
A way to make arguments repeatable is to use an 'append' action type:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('-a', action='append')
parser.add_argument('-b', action='append')
parser.add_argument('-c', action='append')
argv = '-a 1 -b 2 -c 3 -a 4 -c 6 -a 7 -b 8 -a 10'
args = parser.parse_args(argv.split())
print args
产生:
Namespace(a=['1', '4', '7', '10'], b=['2', '8'], c=['3', '6'])
不幸的是,它确实丢失了一些信息.无法将"4"与"6"而不是"8"相关联.
Unfortunately it does lose some information. There's no way to associate the '4' with the '6' instead of the '8'.
如果使用'-'分隔参数块,则此迭代解析器可能会完成此任务:
If you use '--' to separate blocks of arguments, then this iterative parser might do the job:
parser = argparse.ArgumentParser()
# SUPPRESS keeps the default None out of the namespace
parser.add_argument('-a', type=int, default=argparse.SUPPRESS, required=True)
parser.add_argument('-b', type=int, default=argparse.SUPPRESS)
parser.add_argument('-c', type=int, default=argparse.SUPPRESS)
argv = '-a 1 -b 2 -c 3 -- -a 4 -c 6 -- -a 7 -b 8 -- -a 10'
arglist = []
rest = argv.split()
while rest:
args,rest = parser.parse_known_args(rest)
rest = rest[1:] # remove the 1st '--'
print args
arglist.append(vars(args))
print arglist
生产:
Namespace(a=1, b=2, c=3)
Namespace(a=4, c=6)
Namespace(a=7, b=8)
Namespace(a=10)
[{'a': 1, 'c': 3, 'b': 2},
{'a': 4, 'c': 6},
{'a': 7, 'b': 8},
{'a': 10}]
我不确定它是否足够健壮.我将-a
设置为必需,因此从其中一个组中省略它会引发错误.
I'm not sure if it is robust enough. I made -a
required, so omitting it from one of the groups will raise an error.
或改编farzad的迭代器:
Or adapting farzad's iterator:
def by_sets(iterator, start):
set = []
for val in iterator:
if set and val == start:
yield set
set = [val]
else:
set.append(val)
yield set
argv = '-a 1 -b 2 -c 3 -a 4 -c 6 -a 7 -b 8 -a 10'
# print list(by_sets(argv.split(), '-a'))
# [['-a', '1', '-b', '2', '-c', '3'], ['-a', '4', '-c', '6'],... ['-a', '10']]
arglist = []
for aset in by_sets(argv.split(), '-a'):
arglist.append(vars(parser.parse_args(aset)))
print arglist
产生:
[{'a': 1, 'c': 3, 'b': 2}, {'a': 4, 'c': 6}, {'a': 7, 'b': 8}, {'a': 10}]
循环也可以理解为:
[vars(parser.parse_args(aset)) for aset in by_sets(argv.split(), '-a')]
这篇关于Argparse,处理可重复的项目集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!