2

Looking at this answer, I could do this:

parser=argparse.ArgumentParser()
parser.add_argument('-D',action='append',help='FOO=BAR')
options = parser.parse_args('-DVAR1=9 -DVAR2=Off'.split())

And I get:

Namespace(D=['VAR1=9', 'VAR2=Off'])

So then saying:

[o.split('=') for o in options.D]

Results in:

[['VAR1', '9'], ['VAR2', 'Off']]

This is basically what I need, but I feel this is a common action that might already have an implementation within the ArgParse package. Is there a more Pythonesque way of doing this?

Community
  • 1
  • 1
Ken Y-N
  • 14,644
  • 21
  • 71
  • 114
  • Use `sys.argv`, which option running first or which option include others ? I am never used this module, maybe i am not use this basically. – dsgdfg Feb 15 '17 at 08:49
  • 1
    Don't think so. However, a dict of vars might be more useful than a list: `vars=dict( [o.split('=') for o in options.D] )` – nigel222 Feb 15 '17 at 09:11
  • Something similar is implemented in the Figura project. See [this](https://github.com/shx2/figura/blob/master/figura/cli.py#L57) – shx2 Feb 15 '17 at 20:36

1 Answers1

1

I think the argparse developers (and other POSIX style parsers) expect you to define --dvar1 and --dvar2 arguments, rather than this open ended approach.

Others have asked about some sort of general key=value input. There's nothing in argparse that handles that directly. So collecting the strings as you do and splitting them after parsing looks fine. What you are doing is as clean and clear as anything I've seen.

You could do that splitting on-the-fly with a type function:

In [38]: import argparse
In [39]: def foo(astr):
    ...:     return astr.split('=')
    ...: 
In [40]: parser=argparse.ArgumentParser()
In [41]: parser.add_argument('-D',action='append',type=foo)
Out[41]: _AppendAction(option_strings=['-D'], dest='D', nargs=None, const=None, default=None, type=<function foo at 0xab0c765c>, choices=None, help=None, metavar=None)
In [42]: options = parser.parse_args('-DVAR1=9 -DVAR2=Off'.split())
In [43]: options
Out[43]: Namespace(D=[['VAR1', '9'], ['VAR2', 'Off']])

python argparse store --foo=bar as args.key='foo', args.value='bar'

takes a different approach - subclassing Action. That would be needed if you wanted

namespace(VAR1='9', VAR2='Off')

(your post processing loop could have written attributes like that to the namespace. Yet another customization trick is to define a custom Namespace class, one that can take the VAR1=9 string and split it as needed.

Community
  • 1
  • 1
hpaulj
  • 221,503
  • 14
  • 230
  • 353