4

Suppose you have a python function, as so:

def foo(spam, eggs, ham):
    pass

You could call it using the positional arguments only (foo(1, 2, 3)), but you could also be explicit and say foo(spam=1, eggs=2, ham=3), or mix the two (foo(1, 2, ham=3)).

Is it possible to get the same kind of functionality with argparse? I have a couple of positional arguments with keywords, and I don't want to define all of them when using just one.

technillogue
  • 1,482
  • 3
  • 16
  • 27

3 Answers3

5

You can do something like this:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('foo',nargs='?',default=argparse.SUPPRESS)
parser.add_argument('--foo',dest='foo',default=None)

parser.add_argument('bar',nargs='?',default=argparse.SUPPRESS)
parser.add_argument('--bar',dest='bar',default=None)

parser.add_argument('baz',nargs='?',default=argparse.SUPPRESS)
parser.add_argument('--baz',dest='baz',default=None)

print parser.parse_args()

which works mostly as you describe:

temp $ python test.py 1 2 --baz=3
Namespace(bar='2', baz='3', foo='1')
temp $ python test.py --baz=3
Namespace(bar=None, baz='3', foo=None)
temp $ python test.py --foo=2 --baz=3
Namespace(bar=None, baz='3', foo='2')
temp $ python test.py 1 2 3
Namespace(bar='2', baz='3', foo='1')

python would give you an error for the next one in the function call analogy, but argparse will allow it:

temp $ python test.py 1 2 3 --foo=27.5
Namespace(bar='2', baz='3', foo='27.5')

You could probably work around that by using mutually exclusive groupings

mgilson
  • 300,191
  • 65
  • 633
  • 696
  • If the arguments have defaults, will I be able to do `test.py --baz=3`? – technillogue Jan 29 '13 at 15:01
  • @Glycan -- You can hack around that with judicious use of `default=argparse.SUPPRESS` and setting the default explicitly. See my update. – mgilson Jan 29 '13 at 15:09
  • Oh, that sucks, that's the behaviour I was looking for. I dislike hacks that don't make sense. – technillogue Jan 29 '13 at 15:21
  • @Glycan -- What behavior are you looking for? The one where you raise an error if foo is specified twice? – mgilson Jan 29 '13 at 15:24
  • If you're going to use `--help`, you may want to set `help=argparse.SUPPRESS` on one of the `add_argument`s if you don't want options to appear twice. – Mark Nov 19 '15 at 16:14
  • Unfortunately it appears that using `argparse.SUPPRESS` doesn't work with `type=`. – CMCDragonkai Oct 12 '18 at 01:56
1

You can also use this module: docopt

swietyy
  • 786
  • 1
  • 9
  • 15
0

I believe this is what you are looking for Argparse defaults

Tuim
  • 2,491
  • 1
  • 14
  • 31