简体   繁体   中英

How to use subparses for optional positional arguments?

I have just started working with argprase , and have the following example main.py which has optional arguments

import os
import numpy
import argparse

def main():
    parser = argparse.ArgumentParser() 
    parser.add_argument('-C','--Chk',type=str, help='Choose arg')
    args = vars(parser.parse_args())
 
    if args['Chk'] == 'compo1':
        print('This is test1')
    elif args['Chk'] == 'compo2':
        print('This is test2')
       
if __name__=='__main__':
    main()

If I use python3 main.py -C compo1 I get the desired result, ie, This is test1 . Now, I would like to add addtional arguments if -C compo1 is called. For example python main.py -C compa1 -d where, -d performs a task, for eg.

This is test1 #output for -C compo1
This is sub task from test1 #2nd output when -d is called 

Also, I would like -d to be the flag when compa2 is called too, but then the output should be different and as specified.

Can anyone suggest how to get additional arguments for optional positional arguments in argparse library ? and can subparses be used for optional arguments and with the same command line flag ?

So the answer from what I can tell is unfortunately no. The argparse module can't distinguish between the orderings which you would like to distinguish between. I did however find some decent workarounds to this issue at

Find the order of arguments in argparse python3

I coded the following implementation scheme for your setup:

import argparse, sys
parser = argparse.ArgumentParser(description="Usage: [-C CHK -d]")
parser.add_argument('-C','--Chk', type=str, help='Choose arg')
parser.add_argument('-d', default=False, action="store_true", help='d bool of CHK option')
args = parser.parse_args()

def get_arg_index(args: list, name: str):
    return next((i for i, v in enumerate(args) if v.startswith(name)), None)

if args.Chk:
    if args.d:
        # if chk was called with 'd' submodule, check ordering is correct.
        idx_Chk = (get_arg_index(sys.argv, "-C") if "-C" in sys.argv else get_arg_index(sys.argv, "--Chk"))
        idx_d = get_arg_index(sys.argv, "-d")
        assert idx_Chk + 2  == idx_d, \
            "Error. The index of the --foo and -d flags was not separated by exactly one arg. "
        parser.print_help()
        sys.exit()

Since the argparse help won't display the formatting that you're trying to encourage, I'd recommend writing a detailed description message to indicate where the -d flags go. Hope this helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM