2015-04-28 2 views
0

Код ниже принимает аргументы командной строки для mode, такие как -m fizz и -m fizz bazz. Это, как и ожидалось, передает аргументы главной функции как ['fizz', 'bazz'] (для второго примера выше). Кажется, пользователь-недружелюбно передать аргументы командной строки с пробелами, поэтому я бы хотел, чтобы argparse принимал список, разделенный запятыми, например. -m fizz,bazz или -m ['fizz','bazz']. Как я могу изменить код ниже, чтобы сделать это? Благодаря!Python argparse a list input

import agrparse 
... 
parser.add_argument("-m", "--mode", nargs="*", 
        default=["fizz", "bazz", "razmataz"], 
        help="Comma separated list of mode(s) to use, e.g." 
        "[\"fizz\", \"bazz\"]") 
main(parser.parse_args()) 

ответ

1

С помощью простого скрипта, который печатает sys.argv я получаю

1014:~/mypy$ python echoargv.py -m ['fizz','bazz'] 
['echoargv.py', '-m', '[fizz,bazz]'] 
1014:~/mypy$ python echoargv.py -m fizz,bazz 
['echoargv.py', '-m', 'fizz,bazz'] 
1015:~/mypy$ python echoargv.py -m fizz, bazz 
['echoargv.py', '-m', 'fizz,', 'bazz'] 
1016:~/mypy$ python echoargv.py -m ['fizz', 'bazz'] 
['echoargv.py', '-m', '[fizz,', 'bazz]'] 
1016:~/mypy$ python echoargv.py -m fizz bazz 
['echoargv.py', '-m', 'fizz', 'bazz'] 

Вот что ваш parser должен работать.

Последний случай, когда каждая строка является отдельным элементом в sys.argv, является простейшей и представляет собой то, что ваш nargs='*' предназначен для обработки. Он должен вернуться Namespace(mode = ['fizz','bazz'])

У вас есть 2 варианта. Вы можете очистить sys.argv, прежде чем передавать его на номер parser. Или вы можете посмотреть атрибут args.mode после разбора и очистить его по мере необходимости.

Например, 'fizz,bazz' может быть разделен на ,. '[fizz,bazz]' необходимо сначала отключить []. Другие требуют удаления дополнительных , '.

Вы можете сделать это разделение и очистку в пользовательском классе Action, но это не спасет вас от какой-либо работы.


Обычай type также может быть использован для разделения строк

In [170]: def foolist(astring): 
    alist=astring.strip('[').strip(']').split(',') 
    alist = [a.strip() for a in alist if len(a)] 
    return alist 

In [171]: p=argparse.ArgumentParser() 

In [172]: p.add_argument('-m',type=foolist,nargs='*') 
Out[172]: _StoreAction(option_strings=['-m'], dest='m',... 

In [173]: p.parse_args(['-m','one','two']) 
Out[173]: Namespace(m=[['one'], ['two']]) 

In [174]: p.parse_args(['-m','one,two']) 
Out[174]: Namespace(m=[['one', 'two']]) 

In [175]: p.parse_args(['-m','[one, two]']) 
Out[175]: Namespace(m=[['one', 'two']]) 

вниз сторона к этому, что списки вложены. Можно использовать значение по умолчанию nargs, но это не позволит использовать списки с ограниченным пространством. Но есть стандартные способы python для выравнивания вложенного списка.

+0

спасибо. Да, это можно обработать после разбора, вызвав 'args.mode [0] .split (',')', но я ищу решение, в котором argparse может быть задан для самостоятельной обработки ввода, разделенного запятыми. – BoltzmannBrain

+0

Затем вам нужно создать собственное действие, которое может выполнять разделение. Нет никаких предопределенных колоколов или свистков, которые сделают это для вас. Посмотрите на пример в документах, напечатайте 'values' для ваших желаемых аргументов и обработайте их. – hpaulj

+1

Я добавил пример типа – hpaulj