Anshul
Anshul

Reputation: 730

python read in multiple key value (dict) from command line into a variable

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

Answers (1)

Thomas Orozco
Thomas Orozco

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

Related Questions