Here's a parser that handles a repeated 2 argument optional - with names defined in the metavar:
parser=argparse.ArgumentParser()
parser.add_argument('-i','--input',action='append',nargs=2,
metavar=('url','name'),help='help:')
In [295]: parser.print_help()
usage: ipython2.7 [-h] [-i url name]
optional arguments:
-h, --help show this help message and exit
-i url name, --input url name
help:
In [296]: parser.parse_args('-i one two -i three four'.split())
Out[296]: Namespace(input=[['one', 'two'], ['three', 'four']])
This does not handle the 2 or 3 argument case (though I wrote a patch some time ago for a Python bug/issue that would handle such a range).
How about a separate argument definition with nargs=3 and metavar=('url','name','other')?
The tuple metavar can also be used with nargs='+' and nargs='*'; the 2 strings are used as [-u A [B ...]] or [-u [A [B ...]]].
Using the same option multiple times in Python's argparse - Stack Overflow
How to set several required arguments into an optional group?
How to take set multiple variables using Python argparse, both required and optional variables?
Is it possible to use argparse to make optional positional arguments, and if not, what alternatives are available?
Here's a parser that handles a repeated 2 argument optional - with names defined in the metavar:
parser=argparse.ArgumentParser()
parser.add_argument('-i','--input',action='append',nargs=2,
metavar=('url','name'),help='help:')
In [295]: parser.print_help()
usage: ipython2.7 [-h] [-i url name]
optional arguments:
-h, --help show this help message and exit
-i url name, --input url name
help:
In [296]: parser.parse_args('-i one two -i three four'.split())
Out[296]: Namespace(input=[['one', 'two'], ['three', 'four']])
This does not handle the 2 or 3 argument case (though I wrote a patch some time ago for a Python bug/issue that would handle such a range).
How about a separate argument definition with nargs=3 and metavar=('url','name','other')?
The tuple metavar can also be used with nargs='+' and nargs='*'; the 2 strings are used as [-u A [B ...]] or [-u [A [B ...]]].
This is simple; just add both action='append' and nargs='*' (or '+').
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('-i', action='append', nargs='+')
args = parser.parse_args()
Then when you run it, you get
In [32]: run test.py -i input1_url input1_name input1_other_var -i input2_url i
...: nput2_name input2_other_var -i input3_url input3_name
In [33]: args.i
Out[33]:
[['input1_url', 'input1_name', 'input1_other_var'],
['input2_url', 'input2_name', 'input2_other_var'],
['input3_url', 'input3_name']]
How do you deal with multiple inputs via argparse, especially when there are default inputs and optional inputs?
Within my script file.py, users must input two parameters, which I have in a list
parameters_list = [parameter1, parameter2, parameter3] parameter1 = "" # normally in the script, I would set these parameter2 = "" parameter3 = ""
The third parameter parameter3 is a default parameter.
Now, to my mind, users could include the flags at run time python file.py --parameters = 'parameter1', 'parameter2'
parser = argparse.ArgumentParser()
parser.add_argument('parameters', nargs = '*', help = 'input program parameters')
params = parser.parse_args()However, (1) this doesn't parse how users have input the parameters`, i.e.
--parameters = 'parameter1', 'parameter2'
(2) How do you deal with the default parameter parameter3? At the moment, this will throw at error, as the variable parameter3 has been defined in the script, but isn't defined by argparse.
I am trying to use argparse to take arguments from user input, and I basically want them to either be able to process an infile into an output, or update the script resources. So if the user wants to use the script, they would do something like:
myscript.py "infile.txt" "path/to/output/dir"
or if they need to update, I'd like to have the option to just do the following and ignore the in/out arguments completely:
myscript.py --update
This seems like a very trivial thing but I'm not quite sure how to implement it, or if it's even possible using argparse. If it is not, what other options are available to do accomplish what I'd like to do? Thank you in advance!
A nargs='?' flagged option works in 3 ways
Copyparser.add_argument('-d', nargs='?', default='DEF', const='CONST')
commandline:
Copyfoo.py -d value # => args.d == 'value'
foo.py -d # => args.d == 'CONST'
foo.py # => args.d == 'DEF'
https://docs.python.org/3/library/argparse.html#const
Taking advantage of that, you shouldn't need anything like this erroneous -d -o flag.
If you don't use the const parameter, don't use '?'
Copyparser.add_argument('--user','-u', nargs='?', const='CONST', default='default_user')
parser.add_argument('--output','-o', default='default_outfile')
parser.add_argument('--input','-i', default='default_infile')
Do you want to have something like this:
Copyimport argparse
def main():
parser = argparse.ArgumentParser(
description='Check-Access Reporting.',
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
parser.add_argument(
'-d',
dest='discrepancy',
action='store_true',
help='Generate discrepancy report.',
)
parser.add_argument(
'--input',
'-i',
default='users.txt',
help='Input file for the report.',
)
parser.add_argument(
'--output',
'-o',
default='reports.txt',
help='Output file for the report.',
)
args = parser.parse_args()
if args.discrepancy:
print('Report type: {}'.format(args.report_type))
print('Input file: {}'.format(args.input))
print('Output file: {}'.format(args.output))
else:
print('Report type is not specified.')
if __name__ == '__main__':
main()
Result of option --help:
usage: ptest_047.py [-h] [-d] [--input INPUT] [--output OUTPUT]
Check-Access Reporting.
optional arguments:
-h, --help show this help message and exit
-d generate discrepancy report (default: False)
--input INPUT, -i INPUT
input file for the report (default: users.txt)
--output OUTPUT, -o OUTPUT
output file for the report (default: reports.txt)
Without any option (or missing option -d):
Report type is not specified.
With option -d:
Report type: discrepancy
Input file: users.txt
Output file: reports.txt
With -d --input input.txt --output output.txt:
Report type: discrepancy
Input file: input.txt
Output file: output.txt
The premise behind your question is mistaken.
>>> import argparse
>>> p = argparse.ArgumentParser()
>>> p.add_argument('-a')
>>> p.parse_args()
Namespace(a=None)
The -a argument is already optional by default (you don't need required=False), and its default is already None, ensuring that args.a exists without any manual intervention.
You have to opt-in to having no default at all.
>>> p.add_argument("-b", default=argparse.SUPPRESS)
>>> p.parse_args()
Namespace(a=None)
So yes, it probably is a good idea to have some default, and argparse acknowledges that by providing one.
So some clarifications here. To answer this question for python specifically, argparse does in fact default optional argument values to None. Your problem arises from having multiple subcommands that take different arguments, but go through the same code flow. If you pass the same args from subcommands a, b, c that have different options, then you do have to handle each option that is not common across all three. In that workflow, I would recommend backfilling each option that is not guaranteed to exist.
Hi
I'd like to pass arguments like this to my script:
`--input somefile --option1 --option2 --input somefile2 --option2`
and I'd like to be able to tell which `options` were assigned to which `input`.
So in my case I'd like to know that for input `somefile` `option1` and `option2` were used and for `somefile2` only `option2`.
Is it possible to achieve with `argparse`?