Python argparse a list input

拟墨画扇 提交于 2020-01-06 19:06:43

问题


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:


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.



来源:https://stackoverflow.com/questions/29922885/python-argparse-a-list-input

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!