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