简体   繁体   中英

Python argparse a list input

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM