0

I have been trying to execute my python script with some arguments passed. The way I want it to be is something like this:

python script.py filepath

but also to support this

python script.py filepath1 filepath2

My implementation has been:

parser = argparse.ArgumentParser()
mand = parser.add_argument_group("Mandatory arguments")
mand.add_argument("path1", help = "path1")
opt = parser.add_argument_group("Optional arguments")
opt.add_argument("path2", help = "path2")
args = parser.parse_args()

It seems to ask for both arguments. Does anyone have any suggestion as to what is the proper way to do this? One of my thoughts was to do two argument groups; one with the path1 and the other with both paths, but it still requested both.

Thanks guys and gals!

P.S. Python 2.7

1
  • Those argument groups just affect how the help is displayed. They do not affect parsing. For a positional argument, it's the nargs parameter that determines how many values it expects. It also controls the usage display. Commented Jul 18, 2014 at 8:13

2 Answers 2

3

Use nargs="?" (with argparse)

import argparse
parser = argparse.ArgumentParser()
mand = parser.add_argument_group("Mandatory arguments")
mand.add_argument("path1", help = "path1")
opt = parser.add_argument_group("Optional arguments")
opt.add_argument("path2", help = "path2", nargs="?")
args = parser.parse_args()
print args

See usage string:

$ python argscript.py 
usage: argscript.py [-h] path1 [path2]
argscript.py: error: too few arguments

Or with -h:

$ python argscript.py -h
usage: argscript.py [-h] path1 [path2]

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

Mandatory arguments:
  path1       path1

Optional arguments:
  path2       path2

and try it with one positional argument only:

$ python argscript.py alfa
Namespace(path1='alfa', path2=None)

And with two:

$ python argscript.py alfa beta
Namespace(path1='alfa', path2='beta')
Sign up to request clarification or add additional context in comments.

1 Comment

Awesome. Thank you! It is easy to understand it that way
1

Sorry for a bit off topic answer. I prefer using docopt so in case it would be of interest for you.

Using docopt

Install docopt first:

$ pip install docopt

and with the script:

"""script.py
Usage:
    script.py <fname>...
"""

if __name__ == "__main__":
    from docopt import docopt
    args = docopt(__doc__)
    print args

You can use it this way:

Asking for usage script:

$ python script.py 
Usage:
    script.py <fname>...

Calling with one file name:

$ python script.py alfa
{'<fname>': ['alfa']}

Using with two names:

$ python script.py alfa beta
{'<fname>': ['alfa', 'beta']}

Playing with alternative usage descriptions:

Following would allow one or two file names, but never three or more:

"""script.py
Usage:
    script.py <input> [<output>]
"""

if __name__ == "__main__":
    from docopt import docopt
    args = docopt(__doc__)
    print args

3 Comments

It's ok, as long as it adds knowledge to the post. However I forgot to mention a constraint. I can't install a library. (but I will keep it for future personal use)
@MayTheSchwartzBeWithYou Your constrain was implicitly included in using argparse. Btw, you you do not have root permissions, you can still install into user scheme (with pip install --user <packagename> or best install into virtualenv. But this is another topic. There can be other reasons (like easy runnable on any machine with pure Python).
Yes, I know but the tool is going to used by 100 people. I have to run it to the bare minimum dependencies.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.