Python argparse dict arg
Я хочу получить аргумент dict(str -> str)
из командной строки. Предоставляет ли argparse.ArgumentParser
его? Или любая другая библиотека?
Для командной строки:
program.py --dict d --key key1 --value val1 --key key2 --value val2
Я ожидаю следующий словарь:
d = {"key1": "val1", "key2": "val2"}
Ответы
Ответ 1
Здесь другое решение, использующее пользовательское действие, если вы хотите указать пары ключей dict вместе через запятую -
import argparse
import sys
parser = argparse.ArgumentParser(description='parse key pairs into a dictionary')
class StoreDictKeyPair(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
my_dict = {}
for kv in values.split(","):
k,v = kv.split("=")
my_dict[k] = v
setattr(namespace, self.dest, my_dict)
parser.add_argument("--key_pairs", dest="my_dict", action=StoreDictKeyPair, metavar="KEY1=VAL1,KEY2=VAL2...")
args = parser.parse_args(sys.argv[1:])
print args
Бег:
python parse_kv.py --key_pairs 1=2,a=bbb,c=4 --key_pairs test=7,foo=bar
Выход:
Namespace(my_dict={'1': '2', 'a': 'bbb', 'c': '4', 'test': '7', 'foo': 'bar'})
Если вы хотите использовать nargs вместо значений через запятую в строке:
class StoreDictKeyPair(argparse.Action):
def __init__(self, option_strings, dest, nargs=None, **kwargs):
self._nargs = nargs
super(StoreDictKeyPair, self).__init__(option_strings, dest, nargs=nargs, **kwargs)
def __call__(self, parser, namespace, values, option_string=None):
my_dict = {}
print "values: {}".format(values)
for kv in values:
k,v = kv.split("=")
my_dict[k] = v
setattr(namespace, self.dest, my_dict)
parser.add_argument("--key_pairs", dest="my_dict", action=StoreDictKeyPair, nargs="+", metavar="KEY=VAL")
args = parser.parse_args(sys.argv[1:])
print args
Бег
python arg_test4.py --key_pairs 1=2 a=bbb c=4 test=7 foo=bar
Выходы:
values: ['1=2', 'a=bbb', 'c=4', 'test=7', 'foo=bar']
Namespace(my_dict={'1': '2', 'a': 'bbb', 'c': '4', 'test': '7', 'foo': 'bar'})
Ответ 2
Я бы использовал что-то вроде этого:
p = argparse.ArgumentParser()
p.add_argument("--keyvalue", action='append',
type=lambda kv: kv.split("="), dest='keyvalues')
args = p.parse_args("--keyvalue foo=6 --keyvalue bar=baz".split())
d = dict(args.keyvalues)
Вы можете создать настраиваемое действие, которое "добавляет" пар синтаксического анализа непосредственно в словарь, а не просто накапливает список кортежей (key, value)
. (Что я вижу, это то, что сделал skyline75489, мой ответ отличается использованием одного параметра --keyvalue
с настраиваемым типом вместо отдельных опций --key
и --value
для указания пар.)
Ответ 3
Python получает аргументы в виде массива argv
. Вы можете использовать это для создания словаря в самой программе.
import sys
my_dict = {}
for arg in sys.argv[1:]:
key, val=arg.split(':')[0], arg.split(':')[1]
my_dict[key]=val
print my_dict
Для командной строки:
python program.py key1:val1 key2:val2 key3:val3
Вывод:
my_dict = {'key3': 'val3', 'key2': 'val2', 'key1': 'val1'}
Примечание: args будет в строке, поэтому вам придется преобразовать их для хранения числовых значений.
Надеюсь, это поможет.
Ответ 4
просто еще один простой способ:
parser = argparse.ArgumentParser()
parser.add_argument('--key1')
parser.add_argument('--key2')
args = parser.parse_args()
my_dict = args.__dict__
Ответ 5
Аргументы словаря аргументов в строке строки Python argparse_dictionary.py
# $ python argparse_dictionary.py --arg_dict=1=11,2=22;3=33 --arg_dict=a=,b,c=cc,=dd,=ee=,
# Namespace(arg_dict={'1': '11', '2': '22', '3': '33', 'a': '', 'c': 'cc', '': 'dd'})
import argparse
arg_parser = argparse.ArgumentParser()
arg_parser.add_argument('--arg_dict', action=type(b'', (argparse.Action,), dict(__call__=lambda self, parser, namespace, values, option_string: getattr(namespace, self.dest).update(dict([v.split('=') for v in values.replace(';', ',').split(',') if len(v.split('=')) == 2])))), default={}, metavar='KEY1=VAL1,KEY2=VAL2;KEY3=VAL3...')
print(arg_parser.parse_args())
Ответ 6
Прямой способ анализа синтаксического ввода:
program.py --dict d --key key1 --value val1 --key key2 --value val2
:
parser=argparse.ArgumentParser()
parser.add_argument('--dict')
parser.add_argument('--key', action='append')
parser.add_argument('--value', action='append')
args = parser.parse_args()
который должен произвести (если мой психический парсер правильно)
args = Namespace(dict='d', key=['key1','key2'], value=['value1','value2'])
Вы должны иметь возможность построить словарь из этого:
adict = {k:v for k, v in zip(args.key, args.value)}
Использование args.dict
для назначения этого переменной с этим именем требует некоторой обманчивости не-питона. Лучше всего было бы создать элемент в другом словаре с этим именем.
another_dict = {args.dict: adict}
Это решение не выполняет большую проверку ошибок. Например, он не гарантирует, что имеется одинаковое количество ключей и значений. Это также не позволит вам создать несколько словарей (т.е. Повторить аргументы --dict
). Это не требует особого порядка. --dict
может возникнуть после пары --key key1
. Несколько аргументов --value
могут быть вместе.
Связывание key=value
вместе как chepner
происходит вокруг ряда этих проблем.
Ответ 7
В Python 3.6 есть простое решение, если вы просто пытаетесь преобразовать argparse-ввод в словарь. Пример таков:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('-i', '--input', help='the path to the input file')
parser.add_argument('-o', '--output', help='the path to the output file')
args = parser.parse_args()
arguments = dict(args._get_kwargs())
for k, v in arguments.items():
print(k, v)
При заданном вводе командной строки, таком как python3 script_name.py --input 'input.txt' --output 'output.txt'
код будет выводиться на терминал:
input input.txt
output output.txt
Ответ 8
Что касается текущих библиотек, таких как argparse, docopt и нажмите, ни одна из них не поддерживает использование аргументов dict
. Лучшее решение, о котором я могу думать, - создать пользовательский argparse.Action
, чтобы поддерживать его самостоятельно:
import argparse
class MyAction(argparse.Action):
def __init__(self, option_strings, dest, nargs=None, **kwargs):
super(MyAction, self).__init__(option_strings, dest, nargs, **kwargs)
def __call__(self, parser, namespace, values, option_string=None):
print '%r %r %r' % (namespace, values, option_string)
value_dict = {}
values.reverse()
while len(values) > 0:
v = eval(values.pop()).lstrip('--') # This is like crazy hack, I know.
k = eval(values.pop())
value_dict[k] = v
setattr(namespace, self.dest, value_dict)
parser = argparse.ArgumentParser()
parser.add_argument('-d', action=MyAction, nargs='*')
args = parser.parse_args('-d "--key" "key1" "--value" "val1" "--key" "key2" "--value" "val2"'.split())
print(args)