pythoncommand-line-interfaceargparse

Ordered and repeated flags using argparse


Trying to implement a CLI using argparse without writing my own parser if possible. Basically I would like to use the command line in order to invoke different methods sequentially in a program, i.e.:

my_program.py --doA --doB --doA --doA

I've seen threads with good ideas on how to obtain ordered arguments, but I suppose I would end up with a list like this ['doA', 'doB', 'doA', 'doB'] where I would still need to parse the arguments myself.

Is there any way to exploit tools in argparse in order to help execute these commands in order? Thanks!


Solution

  • Here's a parser that will collect these arguments repeatedly and in order:

    import argparse                                                         
    parser = argparse.ArgumentParser()
    parser.add_argument('--doA', dest='cmd', const='doA', action='append_const');
    parser.add_argument('--doB', dest='cmd', const='doB', action='append_const');
    

    Test:

    args = parser.parse_args('--doA --doB --doA --doA'.split())
    print(args)
    

    Result:

    Namespace(cmd=['doA', 'doB', 'doA', 'doA'])
    

    do something:

    for action in args.cmd: 
        print('action:', action) 
    

    Result:

    action: doA
    action: doB
    action: doA
    action: doA
    

    If I had defined:

    def doA(*args):
       # do something
       pass
    

    and used const=doA, then the args.cmd list would be

    Namespace(cmd=[doA, doB, ...])
    

    and we could write

    for action in args.cmd:
        action(arguments)
    

    argparse docs has something like this for subparses and the set_default command.

    If these are the only arguments you accept this would be over kill. But if there are other options that need argparse this would fit in. But accepting a

    parser.add_argument('--cmd', nargs='*', ...)
    

    would be fine. It could use choices to restrict the input strings, and even a type function to translate the strings into function objects.