Reputation: 730
In Perl, One can easily read in multiple key=value
pair into a variable (a hash
) using Getopt::Long
(see here )
Basically it says
GetOptions ("define=s" => \%defines);
And on command line: <prog> --define os=linux --define vendor=redhat
I have been looking an equivalent in Python
but hasn't found any so far [argparse
] doesn't take in dictionary from bash shell easily see type=dict in argparse.add_argument() . Although I can work around this by reading in the arguments and programmatically create a dictionary out of it, I just wanted to know a clean and simple way to do it (like Perl has)
Upvotes: 2
Views: 1689
Reputation: 55197
Use argparse
with a custom action:
import argparse
import copy
class DictAction(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
try:
k, v = values.split("=", 1)
except ValueError:
raise argparse.ArgumentError(self, "Format must be key=value")
# Implementation is from argparse._AppendAction
items = copy.copy(argparse._ensure_value(namespace, self.dest, {})) # Default mutables, use copy!
items[k] = v
setattr(namespace, self.dest, items)
# Usage:
parser = argparse.ArgumentParser()
parser.add_argument("--define", action=DictAction)
print parser.parse_args("--define k=v --define x=y".split())
# Gives
# Namespace(d={'x': 'y', 'k': 'v'})
print parser.parse_args("--define k=v --define x=y --define z".split())
# Gives
# usage: args.py [-h] [--define D]
# args.py: error: argument --define: Format must be key=value
Note that this won't support having an equals sign inside a parameter, but you can expand on the "dumb" k, v = values.split("=", 1)
to address this.
Upvotes: 4