2015-03-13 3 views
0

Есть ли более элегантный способ передать необязательный список целых чисел в argparse, чем pass a delimited string and parse it later? У меня также есть позиционный аргумент.Пропустить необязательный список для argparse

parser.add_argument('--ids', type=int, nargs='+') 
parser.add_argument('cmd') 

не работает, потому что argparse попытки захватить cmd и жалуется, что он не является целым числом.

В идеале, я хотел бы выполнить одну из

program.py --ids 6,32,12 refresh 
program.py --ids 6 32 12 refresh 

или что-то подобное, но и быть в состоянии

program.py refresh 
+1

Вы можете разобрать строку сразу, а не позже, передав произвольное имя в качестве 'type'. – Kevin

+0

@Kevin a la the ['perfect_square'] (https://docs.python.org/3/library/argparse.html#type) пример? – Michael

+0

Да, точно.Вы можете использовать что-то вроде '' operator.methodcaller ('split', ',') '] (https://docs.python.org/3/library/operator.html#operator.methodcaller) как ваш' type', автоматически разбивать запятые. – Kevin

ответ

2

Если вы просто хотите, чтобы разобрать аргументы вида --ids 1,2,3 (без пробелов), вы можете использовать что-то вроде этого:

def convert(argument): 
    return map(int, argument.split(',')) # 3.x: consider wrapping in list() 

parser.add_argument('--ids', type=convert) 

Это не будет обрабатывать аргументы, разделенные пробелами, однако, вероятно, можно смягчить, что несколько с более умной функцией convert(). Однако вам нужно было бы их процитировать, иначе оболочка передаст их в виде отдельных аргументов.

2

-- это удобный способ сказать «позиционные аргументы начинаются здесь ».

С вашим анализатором, эти работы:

program.py refresh # sets ids=None 
program.py refresh --ids 1 2 3 
program.py --ids 1 2 3 -- refresh 

Вы могли бы дать --ids аргумента по умолчанию (например, []), если вы не любите None.

Любые проблемы с program.py refesh --ids 1,2,3 связаны с тем, как оболочка разбивает вашу командную строку. Посмотрите список sys.argv.

Проблемы с program.py --ids 1 2 3 refresh возникают из-за того, что при обработке --ids анализатор пытается использовать все последующие строки, которые не являются явно флагами (например, с «-»). Он не использует тип «int» для проверки того, какие из них использовать и которые нужно оставить.

Теперь, если ids были позиционными, он будет обрабатывать 1 2 3 refresh:

parser.add_argument('ids',type=int,nargs='+') 
parser.add_argument('cmd') 
parser.parse_args('1 2 3 refresh'.split()) 

Но это потому, что анализатор использует различные стратегии для выделения строк до нескольких позиционных аргументов. Он использует совпадение re, которое выглядит как A+A.


type подход Кевина может быть лучше реализован с помощью простой функции:

def mytype(astring): 
    ll = astring.split(',') 
    return [int(l) for l in ll] 
parser.add_argument('--ids', type=mytype) 

Это может быть обобщена для обработки строки в кавычках, как «1 2 3». type может быть любой функцией, которая берет строку и возвращает требуемые значения, и вызывает ошибку, если она не может выполнить преобразование.

Смежные вопросы