Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python - Using argparse, pass an arbitrary string as an argument to be used in the script

How do I define an arbitrary string as an optional argument using argparse?

Example:

[user@host]$ ./script.py FOOBAR -a -b
Running "script.py"...
You set the option "-a"
You set the option "-b"
You passed the string "FOOBAR"

Ideally, I'd like the position of the arguments to not matter. i.e:

./script.py -a FOOBAR -b == ./script.py -a -b FOOBAR == ./script.py FOOBAR -a -b


In BASH, I can accomplish this while using getopts. After handling all desired switches in a case loop, I'd have a line that reads shift $((OPTIND-1)), and from there I can access all remaining arguments using the standard $1, $2, $3, etc...
Does something like that exisit for argparse?

like image 806
svenglar Avatar asked Jun 18 '13 01:06

svenglar


People also ask

How can I pass a list as a command-line argument with Argparse?

To pass a list as a command-line argument with Python argparse, we can use the add_argument to add the argument. to call add_argument with the argument flag's short and long forms. We set nargs to '+' to let us take one or more argument for the flag.

How do you create an argument parser in Python?

# construct the argument parser and parse the arguments ap = argparse. ArgumentParser() ap. add_argument("-d", "--dataset", required=True, help="Path to the directory of indexed images") ap. add_argument("-f", "--features-db", required=True, help="Path to the features database") ap.


1 Answers

To get exactly what you're looking for, the trick is to use parse_known_args() instead of parse_args():

#!/bin/env python 

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-a', action="store_true")
parser.add_argument('-b', action="store_true")

opts = parser.parse_known_args()
# Print info about flags
if opts[0].a: print('You set the option "-a"')
if opts[0].b: print('You set the option "-b"')
# Collect remainder (opts[1] is a list (possibly empty) of all remaining args)
if opts[1]: print('You passed the strings %s' % opts[1])

EDIT:

The above code displays the following help information:

./clargs.py  -h

usage: clargs_old.py [-h] [-a] [-b]

optional arguments:
  -h, --help  show this help message and exit
  -a
  -b

If you want to inform the user about the optional arbitrary argument, the only solution I can think of is to subclass ArgumentParser and write it in yourself.

For example:

#!/bin/env python 

import os
import argparse

class MyParser(argparse.ArgumentParser):
    def format_help(self):
        help = super(MyParser, self).format_help()
        helplines = help.splitlines()
        helplines[0] += ' [FOO]'
        helplines.append('  FOO         some description of FOO')
        helplines.append('')    # Just a trick to force a linesep at the end
        return os.linesep.join(helplines)

parser = MyParser()
parser.add_argument('-a', action="store_true")
parser.add_argument('-b', action="store_true")

opts = parser.parse_known_args()
# Print info about flags
if opts[0].a: print('You set the option "-a"')
if opts[0].b: print('You set the option "-b"')
# Collect remainder
if opts[1]: print('You passed the strings %s' % opts[1])

Which displays the following help information:

./clargs.py -h

usage: clargs.py [-h] [-a] [-b] [FOO]

optional arguments:
  -h, --help  show this help message and exit
  -a
  -b
  FOO         some description of FOO

Note the addition of the [FOO] in the "usage" line and the FOO in the help under "optional arguments".

like image 190
jedwards Avatar answered Nov 07 '22 15:11

jedwards