paul j3 <[email protected]> added the comment:
Let's see if I can clarify somethings. But first, I should say that I've
worked with this code for so long, that I may miss things that could confuse a
beginner.
A basic distinction is between "optionals" and "positionals". I put those in
quotes because that's not the same as "required or not". Talk about "options"
in commandline arguments goes way back (see getopt, and optparse).
An "optional" is identified by a flag string, such as "-f" or "--foo", short or
long, single or double dash. I prefer to call these "flagged arguments".
"optionals" can occur in any order, and even repeatedly.
A "postional" is identified by position, without any sort of flag string. In
earlier parsers, these where the extras, the strings that weren't handled by
"options". These can only occur in the defined order.
Conventionally, optionals come first, and positionals at the end. That's how
most "help/usage" messages display them. But argparse tries to handle them in
any order.
Both kinds can take a "nargs" parameter. This specifies how many arguments (or
strings) are required, either following the flag string, or as part of
position. Obviously if you don't specify the flag, you don't have to provide
its arguments either.
There's another point of confusion. "parse.add_argument" creates an "Action",
also called an "argument". And each "action" has a 'nargs' that specifies how
many "arguments" go along with it. Sorry.
The default "nargs" value is "None", which means 1 string. "?" means zro or
one (optional, but in a different sense than flagged). "*" means any number.
"+" means one or more. nargs could also be a number, e.g. "2". There isn't
anything that specifies "2 or more" or "2 or 3" (though that has been
requested). "?+*" are used in basically the same sense as in regex/re patterns.
There's another parameter, "action", which also controls the number of required
strings. With "store_true" no string is allowed after the flag, effectively
"nargs=0" (this action makes no sense for positionals). It's actually of
subclass of "store_const", with a default "False" and const "True".
With a flagged argument, you may also specify a "required" parameter. That's
convenient, but does lead to confusing terminology. "optionals" may be
"required", and a "positional" with "?" is optional/not-required.
Since "+" and "*" allow many strings, something has to define the end of that
list. That end is either the end of the input, or the next flag string. If you
are just using flagged arguments this isn't a problem. But with "positionals",
it is hard to handle more than one open-end nargs. Or to use such a
"positional" after an open-ended "optional". As with regex, these nargs are
"greedy".
In some ways, the documentation is more complicated than the code itself. The
code is well written, with different methods and classes handling different
issues. The code itself does not have a lot of complicated rules and
conditions. The complexity comes from how the different pieces interact.
"flagged vs positional", nargs, and "required" are separate specifications,
though they do have significant interactions.
In your example:
parser.add_argument("outdata", help="Path to output data file")
parser.add_argument("plotTimes", nargs='*', help="Times to plot")
parser.add_argument("outplot", help="Path to output plot file")
"outdata" takes one string. "outplot" takes another. "plotTimes" then gets
anything left over in between. An empty list of strings satisfies its "nargs".
The strings are actually allocated with a regex expression.
With `arg_argument('--foo', nargs='+')`,
--foo one
--foo one two three
are both allowed. With "*",
--foo
is also allowed. For a "positional" omit the "--foo". That means that a
"positional" with "*" is always seen (which can require some special edge case
handling).
----------
nosy: +paul.j3
_______________________________________
Python tracker <[email protected]>
<https://bugs.python.org/issue43876>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com