This is pretty straight forward following the docs:
import argparse
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
read = subparsers.add_parser('read')
read.add_argument('path')
write = subparsers.add_parser('write')
write.add_argument('path')
write.add_argument('value')
print(parser.parse_args(['read', 'foo']))
print(parser.parse_args(['write', 'foo', 'bar']))
Note that this doesn't tell you what parser parsed the arguments. If you want that, you can simply add a dest to the add_subparsers command:
subparsers = parser.add_subparsers(dest='subparser')
Finally, you can add a default attribute for each subparser that you can use to perform the actions specific to that subparser. This is spelled out in the docs too, but for completeness, in our example, it might look something like this1:
import argparse
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest='subparser')
def handle_read(args):
print('Handling read')
print(args)
read = subparsers.add_parser('read')
read.add_argument('path')
read.set_defaults(handler=handle_read)
def handle_write(args):
print('Handling write')
print(args)
write = subparsers.add_parser('write')
write.add_argument('path')
write.add_argument('value')
write.set_defaults(handler=handle_write)
args = parser.parse_args()
args.handler(args)
1I added the dest to subparsers in this example too for illustrative purposes -- Using argparse with handler functions probably makes that attribute on args obsolete.