Как мога най-ефективно да анализирам тези аргументи в 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')

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

Това означава, че потребителят може да извика командата list по следните начини:

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]

където 'list', 'check', 'watch' са буквални низове, докато 'integer', '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-те „командни“ низа и ще постави всичко друго в атрибута „rest“ (като списък с низове). След това можете да интерпретирате тези низове както искате.

person hpaulj    schedule 22.04.2015