wake-up-neo.net

Python argparse dict arg

Ich möchte ein dict(str -> str)-Argument von der Befehlszeile erhalten. Gibt es argparse.ArgumentParser? Oder eine andere Bibliothek?

Für die Befehlszeile:

program.py --dict d --key key1 --value val1 --key key2 --value val2

Ich erwarte folgendes Wörterbuch:

d = {"key1": "val1", "key2": "val2"}
14
orion_tvv

Hier ist eine andere Lösung, die eine benutzerdefinierte Aktion verwendet , wenn Sie Diktierschlüsselpaare durch Kommas getrennt angeben möchten.

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

Laufen:

python parse_kv.py --key_pairs 1=2,a=bbb,c=4 --key_pairs test=7,foo=bar

Ausgabe:

Namespace(my_dict={'1': '2', 'a': 'bbb', 'c': '4', 'test': '7', 'foo': 'bar'})

Wenn Sie nargs anstelle von durch Kommas getrennten verwenden möchten:

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

Laufen

python arg_test4.py --key_pairs 1=2 a=bbb c=4 test=7 foo=bar

Ausgänge:

values: ['1=2', 'a=bbb', 'c=4', 'test=7', 'foo=bar']
Namespace(my_dict={'1': '2', 'a': 'bbb', 'c': '4', 'test': '7', 'foo': 'bar'})
19
storm_m2138

Ich würde so etwas verwenden:

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)

Sie können eine benutzerdefinierte Aktion erstellen, die ein analysiertes Schlüsselwertpaar direkt an ein Wörterbuch anfügt, statt einfach eine Liste von (key, value)-Tupeln zu sammeln. (Was ich sehe, ist das, was Skyline75489 getan hat; meine Antwort unterscheidet sich darin, dass eine einzelne --keyvalue-Option mit einem benutzerdefinierten Typ verwendet wird, anstelle von separaten --key- und --value-Optionen, um Paare anzugeben.)

16
chepner

Python empfängt Argumente in Form eines Arrays argv. Damit können Sie das Wörterbuch im Programm selbst erstellen.

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

Für die Befehlszeile:

python program.py key1:val1 key2:val2 key3:val3

Ausgabe:

my_dict = {'key3': 'val3', 'key2': 'val2', 'key1': 'val1'}

Hinweis: args werden in einem String gespeichert, daher müssen Sie diese konvertieren, um numerische Werte zu speichern.

Ich hoffe, es hilft.

3
divyum

Es gibt eine einfache Lösung in Python 3.6, wenn Sie einfach versuchen, argparse-Eingaben in ein Wörterbuch zu konvertieren. Ein Beispiel ist wie folgt:

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) 

Kommandozeilen-Eingabe wie python3 script_name.py --input 'input.txt' --output 'output.txt' Der Code würde an das Terminal ausgegeben:

input input.txt
output output.txt
1
Brian

Python-Argumente für einzeilige Argumente 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())
1
miszel

nur ein anderer einfacher Weg:

parser = argparse.ArgumentParser()
parser.add_argument('--key1')
parser.add_argument('--key2')
args = parser.parse_args()
my_dict = args.__dict__
0
Clemens69

Eine einfache Möglichkeit zum Analysieren einer Eingabe wie:

program.py --dict d --key key1 --value val1 --key key2 --value val2

ist: 

parser=argparse.ArgumentParser()
parser.add_argument('--dict')
parser.add_argument('--key', action='append')
parser.add_argument('--value', action='append')
args = parser.parse_args()

was sollte produzieren (wenn mein mentaler Parser korrekt ist)

args = Namespace(dict='d', key=['key1','key2'], value=['value1','value2'])

Sie sollten ein Wörterbuch daraus erstellen können mit:

adict = {k:v for k, v in Zip(args.key, args.value)}

Wenn Sie args.dict verwenden, um dies einer Variablen mit diesem Namen zuzuweisen, ist ein Trick mit Un-Python erforderlich. Am besten erstellen Sie ein Element in einem anderen Wörterbuch mit diesem Namen.

another_dict = {args.dict: adict}

Diese Lösung führt keine große Fehlerprüfung durch. Beispielsweise wird nicht sichergestellt, dass die gleiche Anzahl von Schlüsseln und Werten vorhanden ist. Außerdem können Sie nicht mehrere Wörterbücher erstellen (d. H. Wiederholte --dict-Argumente). Es bedarf keiner besonderen Bestellung. --dict könnte nach einem --key key1-Paar auftreten. Mehrere --value-Argumente könnten zusammen sein. 

Durch das Verbinden des key=value als chepner werden einige dieser Probleme gelöst.

0
hpaulj