Use argparse to call different functions

argparse, python

Solution

Default subcommands

If you want to have subcommands, and make one of them default if no subcommand is specified, then you can't use the typical subparser method.

You need to do your argparse in two passes:

parser = ArgumentParser()
parser.add_argument("function", 
                    nargs="?",
                    choices=['function1', 'function2', 'function2'],
                    default='function1',
                    )
args, sub_args = parser.parse_known_args()

if args.function == "function1":
    parser = ArgumentParser()
    parser.add_argument('-a','--a')
    parser.add_argument('-b','--b')
    parser.add_argument('-c','--c')
    args = parser.parse_args(sub_args)
    function1(args.a, args.b, args.c)
elif args.function == "function2":
    ...
elif args.function == "function3":
    ...

Handling `--help`

If you want `--help` option to be useful, you need to do a bit more work:

- We need to manually handle help because sometimes we want the overall help, and sometimes we want the subcommand's help

- We can't give a default subcommand straight away because we need to be able to tell if it was specified or not

This should do the trick:

# Parse the subcommand argument first
parser = ArgumentParser(add_help=False)
parser.add_argument("function", 
                    nargs="?",
                    choices=['function1', 'function2', 'function2'],
                    )
parser.add_argument('--help', action='store_true')
args, sub_args = parser.parse_known_args(['--help'])

# Manually handle help
if args.help:
    # If no subcommand was specified, give general help
    if args.function is None: 
        print parser.format_help()
        sys.exit(1)
    # Otherwise pass the help option on to the subcommand
    sub_args.append('--help')

# Manually handle the default for "function"
function = "function1" if args.function is None else args.function

# Parse the remaining args as per the selected subcommand
parser = ArgumentParser(prog="%s %s" % (os.path.basename(sys.argv[0]), function))
if function == "function1":
    parser.add_argument('-a','--a')
    parser.add_argument('-b','--b')
    parser.add_argument('-c','--c')
    args = parser.parse_args(sub_args)
    function1(args.a, args.b, args.c)
elif function == "function2":
    ...
elif function == "function3":
    ...

Problem

I am new on Argparse module. I have almost finished my script but there is something I cannot find a way to do it. Here is the script: ``` import argparse def function1(a, b, c): #mystaff def function2(e, f): #mystaff def function3(g): #mystaff if __name__ == '__main__': parser = argparse.ArgumentParser(description='blahblah') parser.add_argument('-a','--a', help='blahblah', required=False, default="defaultvalue") parser.add_argument('-b','--b', help='blahblah', required=False) ....... args = parser.parse_args() function1(args.a,args.b,args.c) ``` I want to call the script from command prompt. Now, I can use this for example to call the `function1`: `python myscript.py -a <var>` What I want is: `python myscript.py -a <var>`: call the function1 as it is now `python myscript.py function2 -c <var>`: call the function2 only `python myscript.py function3 -g <var>`: call the function3 only So, if I don't specify the function, function1 is the default, otherwise I have to pass the function name from the command prompt too. Any ideas?

Original source