I want to create a CLI using Python and argparse
. The CLI should have options to specify a list of values, and also to dynamically specify the type of the values (str
, int
, float
, etc.) in that list (all arguments in the list have the same type). The values in the list must be converted to the specified type.
I have the following baseline implementation, which does work, but if feels a bit clunky, especially when adding more complex types (or even functions which process the input list of arguments). I was wondering if there is a built-in/smoother/more canonical way to do this?
script.py
:
import argparse
arg_type_dict = {t.__name__: t for t in [str, int, float]}
def main(
sweep_arg_type: str,
sweep_arg_vals: list,
):
arg_type = arg_type_dict[sweep_arg_type]
val_list = [arg_type(val_str) for val_str in sweep_arg_vals]
print(val_list)
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--sweep_arg_vals", required=True, nargs="+")
parser.add_argument(
"--sweep_arg_type",
required=True,
choices=sorted(arg_type_dict.keys()),
)
args = parser.parse_args()
main(
args.sweep_arg_type,
args.sweep_arg_vals,
)
Usage examples:
python script.py -h
python script.py --sweep_arg_type int --sweep_arg_vals 0 1 10 -3
python script.py --sweep_arg_type float --sweep_arg_vals 0 1 10 -3
python script.py --sweep_arg_type float --sweep_arg_vals 1.2 3.4
python script.py --sweep_arg_type str --sweep_arg_vals abc def lmnop
I believe the second option in your own solution is the simplest to implement. Note that the arguments are simply JSON values.
import argparse
import json
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--sweep_arg_vals", required=True, type=json.loads)
args = parser.parse_args()
print(args.sweep_arg_vals)
if __name__ == "__main__":
main()
Sample runs
python3 my.py --sweep_arg_vals '[0, 1, 10, -3]'
[0, 1, 10, -3]
python3 my.py --sweep_arg_vals '[1.1, 1.2]'
[1.1, 1.2]
python3 my.py --sweep_arg_vals '["abc", "def", "lmnop"]'
['abc', 'def', 'lmnop']
type=json.loads
, which does the conversionnargs="+"