Как я могу наиболее эффективно анализировать эти аргументы в python?

Итак, я пытаюсь придумать стратегию, используя библиотеку argparse.

Вот как я хочу взаимодействовать с моей программой:

$ program list [<number>] 
$ program check <name>
$ program watch <name> [<quality>]

Прямо сейчас у меня есть парсер аргументов, подобный следующему:

parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument('list')
group.add_argument('check')
group.add_argument('watch')

Но как я могу добавить необязательный аргумент, скажем, целое число, к существующему аргументу?

Это означает, что пользователь может вызвать команду списка следующими способами:

program list 

Где действие списка будет вызываться со значением по умолчанию или:

program list 10

Где действие списка будет вызываться с аргументом 10.

Я видел параметр подкоманды в документации, но столкнулся с проблемой, когда у меня был бы вспомогательный парсер для аргументов списка, но тогда мне нужно было бы добавить флаг, например -n, а затем указать номер. Возможно, это лучший способ сделать это? Но мне нравится идея просто указать номер, если вы хотите, или опустить его, если вы этого не сделаете.

Я пытаюсь добиться хорошей практики? Возможно ли это с argparse?


person Spencer Wood    schedule 22.04.2015    source источник
comment
Вы уже смотрели здесь?   -  person Hai Vu    schedule 23.04.2015
comment
И здесь.   -  person tommy.carstensen    schedule 23.04.2015
comment
Я не думаю, что он хочет обрабатывать несколько подпарсеров одновременно.   -  person hpaulj    schedule 23.04.2015


Ответы (1)


Этот образец сбил меня с толку. В конце я набросал реализацию подпарсера, которая, как мне кажется, помогает.

parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument('list')
group.add_argument('check')
group.add_argument('watch')

Он ожидает 3 строки и назначит их 3 атрибутам.

Однако вы не можете поместить 3 «позиционных» аргумента во взаимоисключающую группу. Один необязательный позиционный (да, терминология сбивает с толку) может быть в такой группе, но остальные должны быть «необязательными» (помечены).


Возвращаясь к вашему первоначальному списку. Это разные шаблоны, которые вы хотели бы принять

program list [integer]
program check name
program watch name [quality]

где «список», «проверка», «наблюдение» — это буквальные строки, а «целое число», «имя», «качество» — имена переменных.

Если это так, то подпарсеры, вероятно, лучший выбор. nargs='?' можно использовать, чтобы сделать позиционные аргументы «необязательными».

parser = argparse.ArgumentParser()
sp = parser.add_subparsers(dest='cmd')  # put the command string in `cmd` attribute
p1 = sp.add_parser('list')
p2 = sp.add_parser('check')
p3 = sp.add_parser('watch')
p1.add_argument('value',dtype=int, nargs='?') # ok with 0 or 1 values
p2.add_argument('name')
p3.add_argument('name')
p3.add_argument('quality',nargs='?')

value и quality получат значение по умолчанию, если ни одно из них не указано явно. По умолчанию default равно None. Но вы можете определить значимую альтернативу, например. default=0 для целочисленного значения.


Вы также можете определить парсер, например:

parser = ...
parser.add_argument('command', choices=['list','check','watch'])
parser.add_argument('rest', nargs='*')

Это будет ожидать одну из 3 строк «команды» и помещать что-либо еще в атрибут «остальное» (в виде списка строк). Затем вы можете интерпретировать эти строки, как хотите.

person hpaulj    schedule 22.04.2015