Home > other >  Python argparse: How to make an initial parameter determine how many parameters come after?
Python argparse: How to make an initial parameter determine how many parameters come after?

Time:01-19

I'd like to do the following, where the type specified dictates what parameters I can use after.

For example, for cmd1, I'd expect a param1 and param2.

For cmd2, I'd expect a param3, param4, param5, and param6.

For cmd3, I'd expect no parameters.

If I don't specify the expected parameters, an error should be shown.


Also, is there someway I could make it so that issuing a -h would show the different combinations allowed?

In all situations, there may be other tags that could be specified, such as --id 5 or --config 1.

Is this possible with python's argparse?

I.e.,

python test.py --type cmd1 param1 param2 --id 5

python test.py --config 2 --type cmd2 param3 param4 param5 param6

python test.py --type cmd3 --config 1

CodePudding user response:

This use of subcommands will get most of what you want. Read the docs for explainations

#python test.py --type cmd1 param1 param2 --id 5
#python test.py --config 2 --type cmd2 param3 param4 param5 param6
#python test.py --type cmd3 --config 1

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--config', type=int)
parser.add_argument('--id', type=int)
sp = parser.add_subparsers(dest='type', required=True)
sp1 = sp.add_parser('cmd1')
sp1.add_argument('param1')
sp1.add_argument('param2')
sp2 = sp.add_parser('cmd2')
sp2.add_argument('parame1')
# etc
sp3 = sp.add_parser('cmd3')

args = parser.parse_args()
print(args)

test cases

1535:~/mypy$ python3 stack70763135.py -h
usage: stack70763135.py [-h] [--config CONFIG] [--id ID] {cmd1,cmd2,cmd3} ...

positional arguments:
  {cmd1,cmd2,cmd3}

optional arguments:
  -h, --help        show this help message and exit
  --config CONFIG
  --id ID

1535:~/mypy$ python3 stack70763135.py --id 5 cmd1 foo1 foo2
Namespace(config=None, id=5, param1='foo1', param2='foo2', type='cmd1')
1535:~/mypy$ python3 stack70763135.py --config 2 cmd2 foo1
Namespace(config=2, id=None, parame1='foo1', type='cmd2')
1536:~/mypy$ python3 stack70763135.py --config 3 cmd3
Namespace(config=3, id=None, type='cmd3')

The help's might be more fragmented that what you want, but the info is all there.

id and config have to come before the cmd entries.

CodePudding user response:

You should be able to use nargs, I believe. For example:

parser.add_argument('--cmd1', nargs=2)  # expects 2 parameters for this argument

nargs will save the parameters into a list (even if you set it to 1!). There are even special characters you can use for nargs, such as doing nargs='?' to get an indeterminate number of parameters.

CodePudding user response:

this should work:

parser.add_argument("--cmd1",nargs=2)
args = parser.parse_args()
print(args.cmd1)

and running it:

>>> py parser.py --cmd1 onlyoneargument
usage: RecFcs.py [-h] [--cmd1 CMD1 CMD1]
RecFcs.py: error: argument --cmd1: expected 2 arguments

if we provide 2 arguments

>>> py parser.py --cmd1 one two
["one","two"]
  •  Tags:  
  • Related