Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

argparse: setting optional argument with value of mandatory argument

Tags:

With Python's argparse, I would like to add an optional argument that, if not given, gets the value of another (mandatory) argument.

parser.add_argument('filename',
                    metavar = 'FILE',
                    type    = str,
                    help    = 'input file'
                    )

parser.add_argument('--extra-file', '-f',
                    metavar = 'ANOTHER_FILE',
                    type    = str,
                    default = ,
                    help    = 'complementary file (default: FILE)'
                    )

I could of course manually check for None after the arguments are parsed, but isn't there a more pythonic way of doing this?

like image 752
Nico Schlömer Avatar asked Aug 17 '12 14:08

Nico Schlömer


People also ask

How do you make an argument optional in Argparse?

Optional Arguments To add an optional argument, simply omit the required parameter in add_argument() . args = parser.

How do you make a parameter optional in Python?

You can define Python function optional arguments by specifying the name of an argument followed by a default value when you declare a function. You can also use the **kwargs method to accept a variable number of arguments in a function. To learn more about coding in Python, read our How to Learn Python guide.

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.

What does Argparse ArgumentParser ()?

The ArgumentParser.parse_args() method runs the parser and places the extracted data in a argparse.Namespace object: args = parser. parse_args() print(args.


2 Answers

As far as I know, there is no way to do this that is more clean than:

ns = parser.parse_args()
ns.extra_file = ns.extra_file if ns.extra_file else ns.filename

(just like you propose in your question).

You could probably do some custom action gymnastics similar to this, but I really don't think that would be worthwhile (or "pythonic").

like image 185
mgilson Avatar answered Sep 18 '22 15:09

mgilson


This has slightly different semantics than your original set of options, but may work for you:

parse.add_argument('filename', action='append', dest='filenames')
parse.add_argument('--extra-file', '-f', action='append', dest='filenames')
args = parse.parse_args()

This would replace args.filename with a list args.filenames of at least one file, with -f appending its argument to that list. Since it's possible to specify -f on the command line before the positional argument, you couldn't on any particular order of the input files in args.filenames.


Another option would be to dispense with the -f option and make filename a multi-valued positional argument:

parse.add_argument('filenames', nargs='+')

Again, args.filenames would be a list of at least one filename. This would also interfere if you have other positional arguments for your script.

like image 35
chepner Avatar answered Sep 18 '22 15:09

chepner