2

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())

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you. Yes this can be handled after parsing by calling args.mode[0].split(','), but I'm looking for a solution where argparse can be specified to handle the comma-separated input on its own.
Then you have to create a custom Action that can do the splitting. There aren't any predefined bells or whistles that will do it for you. Look at the example in the docs, print the values for your desired arguments, and process those.
I added a type example

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.