How to variable number of parameters for one argument in Python with argparse?

I use argparseto offer a mapping option to users of my script as follows:

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

Therefore, I can use the script as follows:

> script.py -m ZigZag

Now I need to provide a new mapping strategy in which the user can specify a custom file that describes the mapping. So I now need something like:

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

How can I achieve this with argparse?

+4
source share
2 answers

, nargs="+", , --help . , mapping_strategy[0] ['ZigZag', 'RoundRobin', 'Custom'].

-p , , mapping_strategy == 'Custom'. " -p, ", mapping_strategy.

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

. , . , , valid_strategies. .

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

:

$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

, -m:

$ 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 Custom, :

$ 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 ZigZag :

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

, , :

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

Windows ? .

, :

$ 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
+3

:

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

. , .

nargs

+2

Source: https://habr.com/ru/post/1612704/


All Articles