Rose
Rose

Reputation: 127

In argparse, how can I make positional arguments depend on the optional arguments?

How can I make positional arguments depend on the optional arguments?

For example:

parser.add_argument("-A", action="store_true", help = "add")
parser.add_argument("-U", action="store_true", help = "update")
parser.add_argument("-D", action="store_true", help = "delete")
parser.add_argument("-L", action="store_true", help = "list")

If I choose -A , I want it to require arguments "name , address, cp number"

But if I choose -L, I don't want it to require anything or when I choose -U it requires another set of arguments.

My end goal is to create a contact book where I can add new contacts, update existing contacts, delete contacts and list contacts. I can do this if I use if else statements but I want to try using argparse.

If I'm using argparse incorrectly, please give me some advice!

Upvotes: 2

Views: 825

Answers (1)

Alex
Alex

Reputation: 7045

This is a good opportunity to use subparsers:

This flips (I think) what you're trying to acheive.

The help text looks like this:

😊 /tmp python3 test.py --help
usage: PROG [-h] {add,update,delete,list} ...

positional arguments:
  {add,update,delete,list}
                        Sub-commands
    add                 ADD help text
    update              UPDATE help text
    delete              DELETE help text
    list                LIST help text

optional arguments:
  -h, --help            show this help message and exit

See '<command> --help' to read about a specific sub-command.

😊 /tmp python3 test.py add -h
usage: PROG add [-h] [--foo FOO]

optional arguments:
  -h, --help  show this help message and exit
  --foo FOO

This skeleton should get you started:

import argparse

def run_command(parser, args):
    if args.command == 'add':
        print(args)
    elif args.command == 'update':
        print(args)
    elif args.command == 'delete':
        print(args)
    elif args.command == 'list':
        print(args)

parser = argparse.ArgumentParser(
    prog='PROG', 
    epilog="See '<command> --help' to read about a specific sub-command."
)
subparsers = parser.add_subparsers(dest='command', help='Sub-commands')

add_parser = subparsers.add_parser('add', help='ADD help text')
add_parser.add_argument("--foo")
add_parser.set_defaults(func=run_command)

update_parser = subparsers.add_parser('update', help='UPDATE help text')
update_parser.add_argument('--bar')
update_parser.set_defaults(func=run_command)

delete_parser = subparsers.add_parser('delete', help='DELETE help text')
delete_parser.add_argument('--baz')
delete_parser.set_defaults(func=run_command)

list_parser = subparsers.add_parser('list', help='LIST help text')
list_parser.add_argument('--qux')
list_parser.set_defaults(func=run_command)

args = parser.parse_args()
if args.command is not None:
    args.func(parser, args)
else:
    parser.print_help()

What the code above does is:

  1. Creates an argparse.ArgumentParser
  2. Adds a subparser called command
  3. Then we create 4 parsers (one for each action) that we can add arguments to
  4. Finally we set a func to run_command which we pass the parser and the args.

Upvotes: 1

Related Questions