I'm creating a script that takes both positional and optional arguments with argparse. I have gone through Doug's tutorial and the python Docs but can't find an answer.
parser = argparse.ArgumentParser(description='script to run')
parser.add_argument('inputFile', nargs='?', type=argparse.FileType('rt'),
parser.add_argument('inputString', action='store', nargs='?')
parser.add_argument('-option1', metavar='percent', type=float, action='store')
parser.add_argument('-option2', metavar='outFile1', type=argparse.FileType('w'),
parser.add_argument('-option3', action='store', default='<10',
args = parser.parse_args()
# rest of script.... blah blah
As you can see, I want 2 positional and 3 optional arguments. However, when I try to run it in the terminal, it doesn't check for the positionals! If I try: python script.py inputfile it will run normally and output error halfway through the script when it cannot find a value for inputString. If I try: python script.py xxx ; the output is:
usage script.py [-h] [-option1] [-option2] [-option3]
Can anyone explain why it doesn't check for the positional arguments?
3 Answers 3
Your problem is that you're specifying nargs='?'
. From the documentation:
'?'
. One argument will be consumed from the command line if possible, and produced as a single item. If no command-line argument is present, the value from default will be produced.
If you leave out the nargs='?'
then the argument will be required, and argparse
will display an error if it is not provided. A single argument is consumed if action='store'
(the default).
You can also specify nargs=1
; the difference is that this produces a list containing one item, as opposed to the item itself. See the documentation for more ways you can use nargs
.
Comments
Works for me.
Code:
#!/usr/bin/python
import argparse
parser=argparse.ArgumentParser(description='script to run')
parser.add_argument('inputFile', nargs='?', type=argparse.FileType('rt'))
parser.add_argument('inputString', action='store', nargs='?')
parser.add_argument('-option1', metavar='percent', type=float, action='store')
parser.add_argument('-option2', metavar='outFile1', type=argparse.FileType('w'))
parser.add_argument('-option3', action='store', default='<10')
args = parser.parse_args()
Execution:
# ./blah.py -h
usage: blah.py [-h] [-option1 percent] [-option2 outFile1] [-option3 OPTION3]
[inputFile] [inputString]
script to run
positional arguments:
inputFile
inputString
optional arguments:
-h, --help show this help message and exit
-option1 percent
-option2 outFile1
-option3 OPTION3
Did you overlook the second line in the argument list?
3 Comments
usage blah.py [inputFile] [inputString] [option1].....
? Thanks!nargs
solved my problem. Basically it was that the script could run with python blah.py inputFile
without inputString given.It works as expected. There is no inputString
if you run it as script.py inputfile
(only one argument is given, but inputString
is the second argument).
narg='?'
means that the argument is optional (they are surrounded by []
in the help message).
inputFile
and`inputString
to be required arguments, why are you settingnargs='?'
?nargs
and it worked! I was using another example and the python docs specifynargs
as consuming 1 argument. I used it so that args.inputFile won't consume both the names given for inputFile and inputString. So is it correct now to say that, you only use nargs for optional arguments? Thanks a lot btw!nargs='*'
ornargs='+'
for multiple arguments; see my answer below and the documentation.