如何在Python中使用argparse为一个参数提供可变数量的参数?

时间:2015-10-22 07:24:25

标签: python argparse

我正在使用argparse向我的脚本用户提出映射选项,如下所示:

parser.add_argument('-m', '--mapping_strategy', 
                    help='mapping strategy', 
                    choices=['ZigZag', 
                    'RoundRobin'])

所以我可以这样使用脚本:

> script.py -m ZigZag

我现在需要提供一种新的映射策略,用户可以在其中指定描述映射的自定义文件。因此我现在需要这样的东西:

> script.py -m Custom /home/manu/custom.map

如何使用argparse实现此目标?

2 个答案:

答案 0 :(得分:3)

您当然可以使用简单的nargs="+",但这有一些缺点,--help输出信息量大大减少。您必须自己进行mapping_strategy[0] ['ZigZag', 'RoundRobin', 'Custom'] -p验证。

现在,另一种方法是要求mapping_strategy == 'Custom'参数指向地图的路径,并要求在import argparse parser = argparse.ArgumentParser() parser.add_argument('-m', "--mapping_strategy", help='valid strategies: ZigZag, RoundRobin, Custom', choices=['ZigZag', 'RoundRobin', 'Custom'] ) parser.add_argument('-p', "--path", help='path to custom map file, required ' 'if using Custom mapping_strategy', ) args = parser.parse_args() if args.mapping_strategy == 'Custom' and args.path == None: parser.error('Custom mapping strategy requires a path') if args.mapping_strategy != 'Custom' and args.path != None: print('Ignoring path parameter, only used for Custom mapping_strategy') print args 时设置该参数。您还可以打印出一个"忽略-p参数,只有自定义映射策略需要#34;警告消息,如果他们提供错误的mapping_strategy。

import argparse

class ValidateMapping(argparse.Action):
    def __call__(self, parser, args, values, option_string=None):
        valid_strategies = ('ZigZag', 'RoundRobin', 'Custom')
        strategy = values[0]
        if strategy not in valid_strategies:
            parser.error('Invalid mapping strategy {}'.format(strategy))
        if strategy == 'Custom':
            if len(values) == 1:
                parser.error('Custom mapping strategy requires a path')
            elif len(values) == 2:
                path = values[1]
            elif len(values) > 2:
                path = '"' + ' '.join(values[1:]) + '"'
            setattr(args, self.dest, [strategy, path])
        else:
            if len(values) > 1:
                print "path to map only used by Custom mapping strategy"
                print "ignoring: ",
                for i in range(1, len(values)):
                    print values[i],
                print
            setattr(args, self.dest, strategy)


parser = argparse.ArgumentParser()

parser.add_argument('-m', "--mapping_strategy",
                    help='valid strategies: ZigZag, RoundRobin, Custom', 
                    nargs="+",
                    action=ValidateMapping,
                    metavar=('mapping strategy', 'path to map')
                    )


args = parser.parse_args()
print args

您也可以使用自定义类来验证参数。此代码提供了更好的帮助消息,以及更好的警告和错误检查。虽然它有点脆弱,因为我复制了valid_strategies列表。但这很容易克服。

$python mapping_strategy.py -h
usage: mapping_strategy.py [-h] [-m mapping strategy [path to map ...]]

optional arguments:
  -h, --help            show this help message and exit
  -m mapping strategy [path to map ...], --mapping_strategy mapping strategy [path to map ...]
                        valid strategies: ZigZag, RoundRobin, Custom

这是帮助输出:

$ python mapping_strategy.py -m 
usage: mapping_strategy.py [-h] [-m mapping strategy [path to map ...]]
mapping_strategy.py: error: argument -m/--mapping_strategy: expected at least one argument

如果您只提供-m:

,会发生什么
$ python mapping_strategy.py -m Custom
usage: mapping_strategy.py [-h] [-m mapping strategy [path to map ...]]
mapping_strategy.py: error: Custom mapping strategy requires a path

如果您输入-m自定义但不提供路径,您会看到以下内容:

$ python mapping_strategy.py -m ZigZag blah blah
path to map only used by Custom mapping strategy
ignoring:  blah blah

如果你给-m ZigZag并添加一条毫无意义的路径会发生什么:

$ python mapping_strategy.py -m Custom c:\My Documents
Namespace(mapping_strategy=['Custom', '"c:My Documents"'])

如果您提供包含空格的路径的自定义选项,那么您将得到什么:

$ python mapping_strategy.py -m Foo
usage: mapping_strategy.py [-h] [-m mapping strategy [path to map ...]]
mapping_strategy.py: error: Invalid mapping strategy Foo

但是谁会使用Windows,或者在目录名中有空格?异教徒。

如果您指定了无效的映射策略,那么这就是您所获得的:

x = centerX + radius * cos(degrees )
y = centerY + radius * sin(degrees )

答案 1 :(得分:2)

将以下行更改为:

parser.add_argument('-m', '--mapping_strategy', 
                     help='mapping strategy', nargs="+")

这将收集列表中的所有位置参数。如果没有至少一个操作,它也会产生错误。

查看nargs documentation