Python argparse with nargs misbehaving

Here is my argparse example say sample.py

import argparse parser = argparse.ArgumentParser() parser.add_argument("-p", nargs="+", help="Stuff") args = parser.parse_args() print args 

Python 2.7.3

I expect the user to supply a list of arguments, separated by spaces after the -p option. For example, if you run

 $ sample.py -pxy Namespace(p=['x', 'y']) 

But my problem is that on startup

 $ sample.py -px -py Namespace(p=['y']) 

What is neither here nor there. I would like one of the following

  • Throw an exception to the user, asking him not to use -p twice, but just put them as one argument
  • Suppose that this is the same parameter and list out ['x', 'y'].

I see that python 2.7 does not do any of them, which bothers me. Can I get python to do one of the two actions above?

+2
source share
2 answers

To create a list from ['x', 'y'], use action='append' . It actually gives

 Namespace(p=[['x'], ['y']]) 

For each -p it gives a list ['x'] as dictated by nargs='+' , but append means add this value to what already has a namespace. The default action simply sets the value, for example. NS['p']=['x'] . I suggest considering the action paragraph in the docs.

optionals allow reuse by design. It allows actions such as append and count . Typically, users do not expect to reuse them or are satisfied with the latter value. positionals (without -flag ) cannot be repeated (except for permitted nargs ).

How to add optional or once arguments? contains some suggestions on how to create the "no repeatts" argument. One of them is to create a custom action class.

+2
source

I ran into the same problem. I decided to go with the usual route of action, as suggested by mgilson.

 import argparse class ExtendAction(argparse.Action): def __call__(self, parser, namespace, values, option_string=None): if getattr(namespace, self.dest, None) is None: setattr(namespace, self.dest, []) getattr(namespace, self.dest).extend(values) parser = argparse.ArgumentParser() parser.add_argument("-p", nargs="+", help="Stuff", action=ExtendAction) args = parser.parse_args() print args 

The result is

 $ ./sample.py -px -py -pzw Namespace(p=['x', 'y', 'z', 'w']) 

However, this would be much more neat if the default option was action='extend' in the library.

0
source

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


All Articles