I've written the following module that handles arguments automatically for all my python codes, whereby I define a dictionary of my program parameters and then argparse uses this to set the command line arguments and the argument type when parsing the call sequence:
import argparse
def get_args(pars):
parser = argparse.ArgumentParser(description='Dynamic arguments')
# add each key of the default dictionary as an argument expecting the same type
for key,val in pars.items():
parser.add_argument('--'+key,type=type(val))
newpars=vars(parser.parse_args())
# Missing arguments=None need to be overwritten with default value
for key,val in newpars.items():
if val==None:
newpars[key]=pars[key]
return(newpars)
if __name__ == "__main__":
# default values:
pars={"a":1,"animal":"cat","f":3.3}
pars=get_args(pars)
print(pars)
This works fine for parsing floats, integers and strings...
python3 test.py --f 2.1
{'a': 1, 'animal': 'cat', 'f': 2.1}
but now I want to add an argument that can be a list of numbers, e.g. say my default pars dictionary is this:
pars={"a":1,"animal":"cat","f":3.3,"l":[1]}
Now this happens:
python3 test.py --l [1,2,3]
{'a': 1, 'animal': 'cat', 'f': 3.3, 'l': ['[', '1', ',', '2', ',', '3', ']']}
That's not what I want, I want to get a list of numbers. In the past when I handled arguments one by one manually I would get around this by using
import ast
val=ast.literal_eval("[1,2,3]")
[1, 2, 3]
But I can't use ast.literal_eval on each argument as it fails when not passed strings containing numerical arguments, so I thought to try this:
try:
parser.add_argument('--'+key,type=type(ast.literal_eval(val)))
except:
parser.add_argument('--'+key,type=type(val))
and define the default list as
l="[1]"
this then returns <class 'list'> for the list argument, but how do I pick that up to conditionally use ast.literal_eval in the parsing ?