Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python argparse treat arguments in different ways

I want to create an optional argument, which will be the '-- ' (double dash and a space) and get everything after it as its value. The problem is that some other optional arguments might appear after '-- '. I don't want these to be parsed as optional arguments, but as the values of '-- '. For example:

python prog1 --foo 1 --bar 2

Here foo and bar are optional arguments with values 1 and 2 respectively

python prog1 --foo 1 --bar 2 -- --foo 4 --bar 14

Here I want foo and bar that come before '-- ' to be parsed as optional arguments. But I want '--foo 4 --bar 14' to be parsed as the value of the optional argument '-- '. I would like to do this without renaming the parameters that come after '-- ' to foo2 and bar2, if possible.

So is this possible? And how could this be implemented?

like image 490
George Tseres Avatar asked Sep 16 '14 15:09

George Tseres


People also ask

What does Argparse ArgumentParser ()?

args = parser.parse_args()# Print "Hello" + the user input argument. print('Hello,', args.name) The code above is the most straightforward way to implement argparse . After importing the library, argparse. ArgumentParser() initializes the parser so that you can start to add custom arguments.

What is action Store_true in Argparse?

The store_true option automatically creates a default value of False. Likewise, store_false will default to True when the command-line argument is not present. The source for this behavior is succinct and clear: http://hg.python.org/cpython/file/2.7/Lib/argparse.py#l861.

Why click instead of Argparse?

Click actually implements its own parsing of arguments and does not use optparse or argparse following the optparse parsing behavior. The reason it's not based on argparse is that argparse does not allow proper nesting of commands by design and has some deficiencies when it comes to POSIX compliant argument handling.


2 Answers

argparse already supports -- as an end-of-options terminator. The only difference is that the default handling treats the following arguments individually. Suppose prog1 simply looks like

import argparse

p = argparse.ArgumentParser()

p.add_argument('--foo')
p.add_argument('--bar')
p.add_argument('remaining', nargs=argparse.REMAINDER)

print p.parse_args()

Then the command

% python prog1 --foo 1 --bar 2 -- --foo 4 --bar 14

produces

Namespace(bar='2', foo='1', remaining=['--', '--foo', '4', '--bar', '14'])

(rather than Namespace(..., remaining='-- --foo 4 --bar 14')). Than can be fixed with a quick post-processing step, if necessary:

args = p.parse_args()
args.remaining = " ".join(args.remaining)
print args

Then the result is

Namespace(bar='2', foo='1', remaining='-- --foo 4 --bar 14')

Discarding the -- argument requires some additional post-processing:

args = p.parse_args()
if args.remaining[0] == "--":
    args = args[1:]
like image 108
chepner Avatar answered Nov 08 '22 01:11

chepner


It looks like the docopt library can do this for you;

From the usage-pattern-format section:

"[--]". Double dash "--" is used by convention to separate positional arguments that can be mistaken for options. In order to support this convention add "[--]" to your usage patterns.

like image 24
will Avatar answered Nov 08 '22 00:11

will