Как преобразовать аргументы командной строки в python в словарь?
Я пишу приложение, которое принимает аргументы командной строки арбитража, а затем передает их на функцию python:
$ myscript.py --arg1=1 --arg2=foobar --arg1=4
а затем внутри myscript.py:
import sys argsdict = some_function(sys.argv)
где argsdict
выглядит так:
{'arg1': ['1', '4'], 'arg2': 'foobar'}
Я уверен, что где-то есть библиотека, но я ничего не могу найти.
EDIT: argparse / getopt / optparse – это не то, что я ищу. Эти библиотеки предназначены для определения интерфейса, который является одним и тем же для каждого вызова. Мне нужно иметь возможность обрабатывать произвольные аргументы. Если, argparse / optparse / getopt имеет функциональность, которая делает это …
- Нужен лучший способ выполнения команд консоли из python и регистрации результатов
- Как загружать файлы с помощью Python?
- в python получить вывод системной команды в виде строки
- В чем разница между запуском ./file.py и python file.py?
- Функция Python в командной строке не работает
.. Могу ли я спросить, почему вы пытаетесь переписать (кучу) колеса, когда у вас есть:
- http://docs.python.org/library/getopt.html
- http://docs.python.org/library/optparse.html
- http://docs.python.org/library/argparse.html
- … и т. д. и т. д. …
?
РЕДАКТИРОВАТЬ:
В ответ на ваше редактирование optparse / argparse (более поздний, доступный только в> = 2.7) достаточно гибкий, чтобы расширяться в соответствии с вашими потребностями, при сохранении согласованного интерфейса (например, пользователь ожидает, что сможет использовать оба --arg=value
и --arg value
, -a value
и -avalue
и т. д. с использованием существующей библиотеки, вам не нужно беспокоиться о поддержке всех этих синтаксисов и т. д.).
Что-то вроде этого?
import sys argsdict = {} for farg in sys.argv: if farg.startswith('--'): (arg,val) = farg.split("=") arg = arg[2:] if arg in argsdict: argsdict[arg].append(val) else: argsdict[arg] = [val]
Немного отличается от указанного, значение всегда является списком.
Вы можете использовать что-то вроде этого:
myscript.py
import sys from collections import defaultdict d=defaultdict(list) for k, v in ((k.lstrip('-'), v) for k,v in (a.split('=') for a in sys.argv[1:])): d[k].append(v) print dict(d)
Результат:
C:\>python myscript.py --arg1=1 --arg2=foobar --arg1=4 {'arg1': ['1', '4'], 'arg2': ['foobar']}
Примечание: значение всегда будет списком, но я думаю, что это более согласовано. Если вы действительно хотите, чтобы последний словарь был
{'arg1': ['1', '4'], 'arg2': 'foobar'}
то вы могли бы просто запустить
for k in (k for k in d if len(d[k])==1): d[k] = d[k][0]
после этого.
Вот пример использования argparse
, хотя это растяжка. Я бы не назвал это полное решение, а хорошим началом.
class StoreInDict(argparse.Action): def __call__(self, parser, namespace, values, option_string=None): d = getattr(namespace, self.dest) for opt in values: k,v = opt.split("=", 1) k = k.lstrip("-") if k in d: d[k].append(v) else: d[k] = [v] setattr(namespace, self.dest, d) # Prevent argparse from trying to distinguish between positional arguments # and optional arguments. Yes, it's a hack. p = argparse.ArgumentParser( prefix_chars=' ' ) # Put all arguments in a single list, and process them with the custom action above, # which convertes each "--key=value" argument to a "(key,value)" tuple and then # merges it into the given dictionary. p.add_argument("options", nargs="*", action=StoreInDict, default=dict()) args = p.parse_args("--arg1=1 --arg2=foo --arg1=4".split()) print args.options
Это то, что я использовал сегодня, это объясняет:
--key=val
, --key
, -key
, -key val
def clean_arguments(args): ret_args = defaultdict(list) for index, k in enumerate(args): if index < len(args) - 1: a, b = k, args[index+1] else: a, b = k, None new_key = None # double hyphen, equals if a.startswith('--') and '=' in a: new_key, val = a.split('=') # double hyphen, no equals # single hyphen, no arg elif (a.startswith('--') and '=' not in a) or \ (a.startswith('-') and (not b or b.startswith('-'))): val = True # single hypen, arg elif a.startswith('-') and b and not b.startswith('-'): val = b else: if (b is None) or (a == val): continue else: raise ValueError('Unexpected argument pair: %s, %s' % (a, b)) # santize the key key = (new_key or a).strip(' -') ret_args[key].append(val) return ret_args
Если вы действительно хотите написать что-то свое, а не надлежащую библиотеку синтаксического анализа командной строки, для вашего ввода это должно работать:
dict(map(lambda x: x.lstrip('-').split('='),sys.argv[1:]))
Вам нужно добавить что-то, чтобы ловить аргументы без «=» в них.
- Наложение непосредственно на фильм с помощью numpy и mencoder
- проверьте, является ли dataframe типами boolean type pandas
- ImportError: нет модуля с именем gdal
- -s означает простой английский
- sys.stdin не закрывается на ctrl-d
- Как узнать, запущена ли программа из командной строки или из Интернета?
- Bash: переменная в одиночной кавычке
- проверка JSON из командной строки с использованием `python -m jsontool` дает« Нет объекта JSON, который может быть декодирован »
- Передайте строку в командную строку
- Выполнение многострочных операторов Python в однострочной командной строке
- Интерактивная оболочка python в 16 раз быстрее командной строки – что случилось?