2017-02-15 7 views
2

Глядя на this answer, я мог бы сделать это:Синтаксический "питон foo.py -DVAR1 = 9 -DVAR2 = Off" с argparse

parser=argparse.ArgumentParser() 
parser.add_argument('-D',action='append',help='FOO=BAR') 
options = parser.parse_args('-DVAR1=9 -DVAR2=Off'.split()) 

И я получаю:

Namespace(D=['VAR1=9', 'VAR2=Off']) 

Итак говоря :

[o.split('=') for o in options.D] 

Результаты в:

[['VAR1', '9'], ['VAR2', 'Off']] 

Это в основном то, что мне нужно, но я считаю, что это общее действие, которое может уже иметь реализацию в пакете ArgParse. Есть ли более питонесский способ сделать это?

+0

Использовать 'sys.argv', какой параметр запускается первым или какой параметр включает другие? Я никогда не использовал этот модуль, возможно, я не использую это в основном. – dsgdfg

+1

Не думайте так. vars может быть более полезным, чем список: 'vars = dict ([o.split ('=') для o в параметрах.D])' – nigel222

+0

Что-то подобное реализовано в проекте Figura. S ee [this] (https://github.com/shx2/figura/blob/master/figura/cli.py#L57) – shx2

ответ

1

Я думаю, что разработчики argparse (и другие парсеры POSIX) ожидают, что вы определите аргументы --dvar1 и --dvar2, а не этот подход с открытым концом.

Другие спросили о каком-то общем key=value вводах. В argparse ничего не обрабатывается напрямую. Так что сбор струн, как вы это делаете, и расщепление их после разбора выглядит хорошо. То, что вы делаете, так же чисто и ясно, как и все, что я видел.

Вы могли бы сделать, что расщепление на лету с type функции:

In [38]: import argparse 
In [39]: def foo(astr): 
    ...:  return astr.split('=') 
    ...: 
In [40]: parser=argparse.ArgumentParser() 
In [41]: parser.add_argument('-D',action='append',type=foo) 
Out[41]: _AppendAction(option_strings=['-D'], dest='D', nargs=None, const=None, default=None, type=<function foo at 0xab0c765c>, choices=None, help=None, metavar=None) 
In [42]: options = parser.parse_args('-DVAR1=9 -DVAR2=Off'.split()) 
In [43]: options 
Out[43]: Namespace(D=[['VAR1', '9'], ['VAR2', 'Off']]) 

python argparse store --foo=bar as args.key='foo', args.value='bar'

другой подход - подклассов Action. Это было бы необходимо, если вы хотите

namespace(VAR1='9', VAR2='Off') 

(ваш цикл постобработки мог написать такие атрибуты, как это к namespace. Еще одна настройка Хитрость заключается в том, чтобы определить пользовательский класс Namespace, тот, который может взять на себя VAR1=9 строку и раскол если это необходимо.