Способ сделать аргументы повторяемым является использование '' на добавление типа действий:
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».
Если вы используете «-», чтобы отделить блоки аргументов, то это итеративный анализатор может сделать работу:
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
, поэтому его удаление из одной из групп вызовет ошибку.
Или адаптации итератор Farzad в:
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')]
Как вы собираетесь указать установить границы в командной строке? использование нескольких пространств - это визуальная справка, но когда ваша оболочка анализирует команду для выполнения, несколько пробелов не помогут. Таким образом, ваше приложение Python просто получит: -a 1 -b 2 -c 3 -a 4 -c 6 -b 8 -a 10'. Как вы теперь определяете наборы? Является ли допустимым предположение о том, что элементы каждого набора сортируются, поэтому вы знаете, что достигли другого набора, потому что раньше вы _c_, и теперь вы достигли _a_? – farzad
Пространства были просто для того, чтобы четко показать возможное взаимодействие. Я согласен, что нет хорошего способа разбить их на множества без необходимого аргумента, спасибо, что, указав это, я должен был упомянуть, что -a - необходимый аргумент, это позволяет нам идентифицировать границы набора. Я думал просто использовать список для каждого аргумента и zip их как кортежи, но это будет некорректно, если отсутствуют некоторые необязательные аргументы. – user3043805