Reputation: 5412
The code below accepts command line arguments for mode
such as -m fizz
and -m fizz bazz
. This, as expected, passes the arguments to the main function as ['fizz', 'bazz']
(for the second example above). It seems user-unfriendly to pass command line arguments with spaces, so I'd like argparse to accept a comma-separated list e.g. -m fizz,bazz
or -m ['fizz','bazz']
. How can I modify the code below to do this? Thanks!
import agrparse
...
parser.add_argument("-m", "--mode", nargs="*",
default=["fizz", "bazz", "razmataz"],
help="Comma separated list of mode(s) to use, e.g."
"[\"fizz\", \"bazz\"]")
main(parser.parse_args())
Upvotes: 2
Views: 2918
Reputation: 231698
With a simple script that prints sys.argv
I get
1014:~/mypy$ python echoargv.py -m ['fizz','bazz']
['echoargv.py', '-m', '[fizz,bazz]']
1014:~/mypy$ python echoargv.py -m fizz,bazz
['echoargv.py', '-m', 'fizz,bazz']
1015:~/mypy$ python echoargv.py -m fizz, bazz
['echoargv.py', '-m', 'fizz,', 'bazz']
1016:~/mypy$ python echoargv.py -m ['fizz', 'bazz']
['echoargv.py', '-m', '[fizz,', 'bazz]']
1016:~/mypy$ python echoargv.py -m fizz bazz
['echoargv.py', '-m', 'fizz', 'bazz']
That's what your parser
has to work with.
The last case, where each string is a separate item in the sys.argv
is simplest, and is what your nargs='*'
is designed to handle. It should return Namespace(mode = ['fizz','bazz'])
You have 2 options. You could clean up sys.argv
before passing it to the parser
. Or you could look at the args.mode
attribute after parsing, and clean it up as needed.
For example 'fizz,bazz'
could be split on ,
. '[fizz,bazz]'
requires stripping off the []
first. Others require removing extra ,
'.
You could do this splitting and cleanup in a custom Action class, but it isn't going to save you any work.
A custom type
could also be used to split strings
In [170]: def foolist(astring):
alist=astring.strip('[').strip(']').split(',')
alist = [a.strip() for a in alist if len(a)]
return alist
In [171]: p=argparse.ArgumentParser()
In [172]: p.add_argument('-m',type=foolist,nargs='*')
Out[172]: _StoreAction(option_strings=['-m'], dest='m',...
In [173]: p.parse_args(['-m','one','two'])
Out[173]: Namespace(m=[['one'], ['two']])
In [174]: p.parse_args(['-m','one,two'])
Out[174]: Namespace(m=[['one', 'two']])
In [175]: p.parse_args(['-m','[one, two]'])
Out[175]: Namespace(m=[['one', 'two']])
A down side to this that the lists are nested. The default nargs
could be used, but it wouldn't allow the regular space delimited lists. But there are standard python ways of flattening a nested list.
Upvotes: 2