Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create arg string from ArgumentParser parsed args in Python

If I have an argparser.ArgumentParser, plus a namespace returned from parser.parse_args, is there a simple way to convert the namespace back into a list of argv such that they could be passed back to the program? Essentially, is there an inverse function of parse_args?

An example scenario:

parser = argparse.ArgumentParser()
parser.add_argument('--example', type=int, default=0)
args = parser.parse_args(argv)

args.example *= 2
new_argv = parser.generate_argv(args)

So if I call:

python my_program.py --example 1

I would want back:

new_argv = ['--example', '2']
like image 846
heyitsbmo Avatar asked Mar 30 '16 21:03

heyitsbmo


1 Answers

I think this has been asked before, though I'm not sure of a good search term.

argparse - Build back command line (found by searching on argparse and sys.argv)

Before we get too far into this question, lets be clear. args=parser.parse_args() is the same as args=parser.parse_args(sys.argv[1:]). But I can imagine cases where you like to know what sys.argv[1:] would produce some arbitrary args. Maybe for testing, maybe for driving someone else's code.

There isn't any code in argparse that does this. But for a limited set of cases you could take information from the defined Actions, and create a plausible sys.argv.

In [432]: parser = argparse.ArgumentParser()    
In [433]: parser.add_argument('--example', type=int, default=0)
Out[433]: _StoreAction(option_strings=['--example'], dest='example', nargs=None, const=None, default=0, type=<type 'int'>, choices=None, help=None, metavar=None)

The list of defined Actions:

In [435]: parser._actions
Out[435]: 
[_HelpAction(option_strings=['-h', '--help'], dest='help', nargs=0, const=None, default='==SUPPRESS==', type=None, choices=None, help='show this help message and exit', metavar=None),
 _StoreAction(option_strings=['--example'], dest='example', nargs=None, const=None, default=0, type=<type 'int'>, choices=None, help=None, metavar=None)]

select the one of interest, and look at some of its attributes:

In [436]: a1=parser._actions[-1]
In [437]: a1.type
Out[437]: int
In [438]: a1.default
Out[438]: 0

Now generate args:

In [439]: args=parser.parse_args(['--example','1'])    
In [440]: args
Out[440]: Namespace(example=1)
In [441]: args.example *= 2

A simple example of creating a list using the new args and information from the Action. Obviously the working code needs to deduce which action to use. For the most common types str() is enough.

In [442]: if args.example != a1.default:
   .....:     print(['--example',str(args.example)])
   .....:     
['--example', '2']

Or I could play with the metavar attribute, and the usage formatter:

In [445]: a1.metavar=str(args.example)
In [446]: parser.print_usage()
usage: ipython2.7 [-h] [--example 2]
like image 63
hpaulj Avatar answered Sep 21 '22 21:09

hpaulj