Python argparse 列表输入

Python argparse a list input

下面的代码接受 mode 的命令行参数,例如 -m fizz-m fizz bazz。正如预期的那样,这会将参数作为 ['fizz', 'bazz'] 传递给主函数(对于上面的第二个示例)。用空格传递命令行参数似乎对用户不友好,所以我希望 argparse 接受逗号分隔的列表,例如-m fizz,bazz-m ['fizz','bazz']。我怎样才能修改下面的代码来做到这一点?谢谢!

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

使用打印 sys.argv 的简单脚本,我得到

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']

这就是您的 parser 必须处理的问题。

最后一种情况,其中每个字符串都是 sys.argv 中的一个单独项目,这是最简单的,也是您的 nargs='*' 旨在处理的情况。应该returnNamespace(mode = ['fizz','bazz'])

你有2个选项。您可以在将 sys.argv 传递给 parser 之前清理它。或者你可以在解析后查看 args.mode 属性,并根据需要清理它。

例如 'fizz,bazz' 可以拆分为 ,'[fizz,bazz]' 需要先剥离 []。其他人需要删除额外的 ,'.

您可以在自定义操作中执行此拆分和清理操作 class,但这不会为您节省任何工作。


自定义 type 也可用于拆分字符串

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']])

不利的一面是列表是嵌套的。可以使用默认的 nargs,但它不允许使用常规的 space 分隔列表。但是有标准的 python 方法可以展平嵌套列表。